{-# 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)))