module Main where
import Control.Monad
primPlusInt :: (Monad m) => Int -> Int -> m Int
primPlusInt a b = return (a + b)
primMinusInt :: (Monad m) => Int -> Int -> m Int
primMinusInt a b = return (a - b)
class Eval a b | a -> b where
eval :: (Monad m) => a -> m b
instance Eval Int Int where
eval = return
instance Eval Bool Bool where
eval = return
instance Eval Char Char where
eval = return
instance (Eval a b) => Eval [a] [b] where
eval [] = return []
eval (x:xs) = do
x' <- eval x
xs' <- eval xs
return (x':xs')
data (Eval a Int, Eval b Int) => FADD a b = FADD a b
instance (Eval a Int, Eval b Int) => Eval (FADD a b) Int where
eval (FADD a b) = do
a' <- eval a
b' <- eval b
primPlusInt a' b'
data (Eval a Int, Eval b Int) => FSUB a b = FSUB a b
instance (Eval a Int, Eval b Int) => Eval (FSUB a b) Int where
eval (FSUB a b) = do
a' <- eval a
b' <- eval b
primMinusInt a' b'
data Ffun a b c = Ffun a b c
instance (Eval a Int, Eval b x, Eval c x) => Eval (Ffun a b c) x where
eval (Ffun a b c) = fun a b c
fun a b c = do
p <- eval a
if p < (0::Int) then eval b else eval c
main = do
putStrLn "bla"
fun (FADD (2::Int) (3::Int)) (FADD (6::Int) (8::Int)) (FSUB (3::Int) (9::Int))
>>= putStrLn . show
fun (FADD (2::Int) (3::Int)) True False
>>= putStrLn . show
fun (FADD (2::Int) (3::Int)) "Neg" "Pos"
>>= putStrLn . show