Valor de expresiones aritméticas generales
Las operaciones de suma, resta y multiplicación se pueden representar mediante el siguiente tipo de datos
data Op = S | R | M
La expresiones aritméticas con dichas operaciones se pueden representar mediante el siguiente tipo de dato algebraico
data Expr = C Int | A Op Expr Expr
Por ejemplo, la expresión
(7-3)+(2*5)
se representa por
A S (A R (C 7) (C 3)) (A M (C 2) (C 5))
Definir la función
valor :: Expr -> Int
tal que valor e
es el valor de la expresión e
. Por ejemplo,
valor (A S (A R (C 7) (C 3)) (A M (C 2) (C 5))) == 14 valor (A M (A R (C 7) (C 3)) (A S (C 2) (C 5))) == 28
Soluciones
A continuación se muestran las soluciones en Haskell y las soluciones en Python.
Soluciones en Haskell
data Op = S | R | M data Expr = C Int | A Op Expr Expr -- 1ª solución -- =========== valor :: Expr -> Int valor (C x) = x valor (A o e1 e2) = aplica o (valor e1) (valor e2) where aplica :: Op -> Int -> Int -> Int aplica S x y = x+y aplica R x y = x-y aplica M x y = x*y -- 2ª solución -- =========== valor2 :: Expr -> Int valor2 (C n) = n valor2 (A o x y) = sig o (valor2 x) (valor2 y) where sig :: Op -> Int -> Int -> Int sig S = (+) sig M = (*) sig R = (-)
Soluciones en Python
from dataclasses import dataclass from enum import Enum Op = Enum('Op', ['S', 'R', 'M']) @dataclass class Expr: pass @dataclass class C(Expr): x: int @dataclass class A(Expr): o: Op x: Expr y: Expr def aplica(o: Op, x: int, y: int) -> int: match o: case Op.S: return x + y case Op.R: return x - y case Op.M: return x * y assert False def valor(e: Expr) -> int: match e: case C(x): return x case A(o, e1, e2): return aplica(o, valor(e1), valor(e2)) assert False