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)