fundeps for extended Monad definition

oleg@pobox.com oleg@pobox.com
Fri, 28 Feb 2003 11:02:18 -0800 (PST)


Hello!

	It seems we can truly implement Monad2 without pushing the
envelope too far. The solution and a few tests are given below. In
contrast to the previous approach, here we lift the type variables
rather than bury them. The principle is to bring the type logic
programming at the level of classes and instances but avoid putting
them at the level of their members.


> class TwoMonadific m a ma | m a -> ma, ma -> m a where
>   unused :: m a -> ()
>   unused = undefined
  
> instance TwoMonadific [] a [a]

> instance TwoMonadific Maybe a (Maybe a)

> class (TwoMonadific m a ma, TwoMonadific m b mb) => Monad2 m a b ma mb 
>  where
>   return2 :: a -> ma
>   bind2   :: ma -> (a -> mb) -> mb  

> instance Monad2 [] a b [a] [b] where
>   return2 x = [x]
>   bind2 l f = concatMap f l

> instance Monad2 Maybe a b (Maybe a) (Maybe b) where
>   return2 x = Just x
>   bind2 Nothing f = Nothing
>   bind2 (Just x) f = f x
  
> test1 = (return2 5) `bind2` (\n -> [1..n]) `bind2` (\n -> [1..n])

> test2 = (return2 5) `bind2` Just `bind2` Just

> *Main> test1
> [1,1,2,1,2,3,1,2,3,4,1,2,3,4,5]
> *Main> test2
> Just 5

It all works in GHC. Hugs complaints about return2:

  ERROR "/tmp/b.hs":11 - Ambiguous type signature in class declaration
  *** ambiguous type : Monad2 a b c d e => b -> d
  *** assigned to    : return2

My version of Hugs isn't up-to-date though.