data Exp = Val Int | Mas Exp Exp | Menos Exp Exp | Por Exp Exp | Div Exp Exp -- Monada {- Con la monada identidad, antes de evaluar Div type T a = a t :: (a -> b) -> T a -> T b t f = f eta :: a -> T a eta a = a mu :: T (T a) -> T a mu tta = tta eval :: Exp -> T Int eval (Val i) = eta i eval (Mas a b) = mu $ t (\x -> mu $ t (\y -> eta (x+y)) (eval b)) (eval a) eval (Menos a b) = mu $ t (\x -> mu $ t (\y -> eta (x-y)) (eval b)) (eval a) eval (Por a b) = mu $ t (\x -> mu $ t (\y -> eta (x*y)) (eval b)) (eval a) -} type T a = Maybe a t :: (a -> b) -> T a -> T b t f = \ta -> case ta of Just a -> Just (f a) Nothing -> Nothing eta :: a -> T a eta = Just mu :: T (T a) -> T a mu tta = case tta of Just ta -> ta Nothing -> Nothing div0 :: T a div0 = Nothing eval :: Exp -> T Int eval (Val i) = eta i eval (Mas a b) = mu $ t (\x -> mu $ t (\y -> eta (x+y)) (eval b)) (eval a) eval (Menos a b) = mu $ t (\x -> mu $ t (\y -> eta (x-y)) (eval b)) (eval a) eval (Por a b) = mu $ t (\x -> mu $ t (\y -> eta (x*y)) (eval b)) (eval a) eval (Div a b) = mu $ t (\x -> mu $ t (\y -> if y == 0 then div0 else eta (x `div` y)) (eval b)) (eval a)