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)