Ir al contenido principal

Evaluación de expresiones aritméticas

Las expresiones aritméticas se pueden definir mediante el siguiente tipo de dato

data Expr  = N Int | V Char | Sum Expr Expr | Mul Expr Expr
             deriving Show

Por ejemplo, (x+3)+(7*y) se representa por

ejExpr :: Expr
ejExpr = Sum (Sum (V 'x') (N 3))(Mul (N 7) (V 'y'))

Definir la función

valor :: Expr -> Maybe Int

tal que (valor e) es 'Just v' si la expresión e es numérica y v es su valor, o bien 'Nothing' si e no es numérica. Por ejemplo:

valor (Sum (N 7) (N 9))                            == Just 16
valor (Sum (Sum (V 'x') (N 3))(Mul (N 7) (V 'y'))) == Nothing
valor (Sum (Sum (N 1) (N 3))(Mul (N 7) (N 2)))     == Just 18

Soluciones

data Expr  = N Int | V Char | Sum Expr Expr | Mul Expr Expr
             deriving Show

-- 1ª solución
-- ===========

valor1 :: Expr -> Maybe Int
valor1 e | null (aux e) = Nothing
         | otherwise    = Just (head (aux e))
    where aux (N x)       = [x]
          aux (V _)       = []
          aux (Sum e1 e2) = [x+y| x <- aux e1, y <- aux e2]
          aux (Mul e1 e2) = [x*y| x <- aux e1, y <- aux e2]

-- 2ª solución
-- ===========

valor2 :: Expr -> Maybe Int
valor2 e | numerico e = Just (aux e)
         | otherwise  = Nothing
    where aux (N x)       = x
          aux (Sum e1 e2) = aux e1 + aux e2
          aux (Mul e1 e2) = aux e1 * aux e2

numerico :: Expr -> Bool
numerico (N _)       = True
numerico (V _)       = False
numerico (Sum e1 e2) = numerico e1 && numerico e2
numerico (Mul e1 e2) = numerico e1 && numerico e2