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)
