data List a = Nil | Cons a (List a) instance (Show a) => Show (List a) where show Nil = "" show (Cons x xs) = show x ++ ", " ++ show xs join :: List (List a) -> List a join Nil = Nil join (Cons xs xss) = cat xs (join xss) cat :: List a -> List a -> List a cat Nil ys = ys cat (Cons x xs) ys = Cons x (cat xs ys) l1 = Cons 1 (Cons 2 Nil) l2 = Cons 3 Nil between :: (Ord a, Num a) => a -> a -> List a between x y | x<=y = Cons x (between (x+1) y) | otherwise = Nil instance Functor List where fmap f Nil = Nil fmap f (Cons x xs) = Cons (f x) (fmap f xs) instance Applicative List where pure x = Cons x Nil Nil <*> _ = Nil _ <*> Nil = Nil (Cons f fs) <*> (Cons x xs) = Cons (f x) (fs <*> xs) instance Monad List where return x = Cons x Nil xs >>= k = join $ fmap k xs test = do x <- between 0 5 y <- between x 5 return (x,y) main = print $ test