{-# OPTIONS -XGADTs #-}
data Option a where
None :: Option a
Some :: a -> Option a
ret :: a -> Option a
ret x = Some x
letb :: Option a -> (a -> Option b) -> Option b
letb None _ = None
letb (Some x) f = f x
raise :: Option a
raise = None
instance Monad Option where
return = ret
x >>= f = letb x f
data Tree a where
Leaf :: a -> Tree a
Node :: Tree a -> Tree a -> Tree a
sumpos :: Tree Integer -> Option Integer
sumpos (Leaf x1) = if x1 >= 0
then return x1
else raise
sumpos (Node n1 n2) = do s1 <- sumpos n1
s2 <- sumpos n2
return (s1 + s2)
sumpos2 :: Tree Integer -> Option Integer
sumpos2 (Leaf x1) = if x1 >= 0
then Some x1
else None
sumpos2 (Node n1 n2) = case sumpos n1 of
None -> None
Some s1 -> case sumpos n2 of
None -> None
Some s2 -> Some (s1 + s2)
instance Show a => Show (Option a) where
show None = "None"
show (Some x) = "Some(" ++ (show x) ++ ")"
t1 = (Node (Leaf 12) (Node (Leaf (-13)) (Leaf 13)))
t2 = (Node (Leaf 12) (Node (Leaf 17) (Leaf 13)))