Valor de expresiones aritméticas generales
Las operaciones de suma, resta y multiplicación se pueden representar mediante el siguiente tipo de datos
1 |
data Op = S | R | M |
La expresiones aritméticas con dichas operaciones se pueden representar mediante el siguiente tipo de dato algebraico
1 2 |
data Expr = C Int | A Op Expr Expr |
Por ejemplo, la expresión
1 |
(7-3)+(2*5) |
se representa por
1 |
A S (A R (C 7) (C 3)) (A M (C 2) (C 5)) |
Definir la función
1 |
valor :: Expr -> Int |
tal que valor e
es el valor de la expresión e
. Por ejemplo,
1 2 |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
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 = (-) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
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 |
La función «valor» se puede definir de la siguiente manera en Haskell:
La función recursivamente recorre la expresión, y en cada nivel verifica si se trata de un número constante (C n), en cuyo caso retorna ese número, o si se trata de una operación (A op e1 e2), en cuyo caso realiza la operación correspondiente (suma, resta o multiplicación) entre los valores de e1 y e2.