Subject: Re: AT solution: rebinding >>= for restricted monads Newsgroups: gmane.comp.lang.haskell.cafe Date: Tuesday 19th December 2006 02:52:41 UTC (over 10 years ago) Hi David, I don't think you need functional dependencies or associated type synonyms to get your example to work. In the past, I have used the abstraction that you are describing (I call it an "indexed monad" and it has a nice categorical definition). Here is how you can define it: > class IxMonad m where > (>>>=) :: m i j a -> (a -> m j k b) -> m i k b > ret :: a -> m i i a Next, you wanted to define an instances that captured the fact that any monad is trivially an indexed monad. Here is how you can do this: > newtype FromMonad m i j a = M { unM :: m a } > > instance Monad m => IxMonad (FromMonad m) where > ret x = M (return x) > M m >>>= f = M (m >>= (unM . f)) We use a newtype to prevent this instance overlapping with other instances. And just for fun we can define another indexed monad: state that supports "strong updates" (i.e., the type of the state can change as you compute): > newtype State i j a = S { unS :: i -> (a,j) } > > instance IxMonad State where > ret x = S (\s -> (x,s)) > S m >>>= f = S (\s1 -> let (a,s2) = m s1 > in unS (f a) s2) Here are some operations to access and modify the state: > get :: State s s s > get = S (\s -> (s,s)) > > set :: s1 -> State s2 s1 s2 > set s1 = S (\s2 -> (s2,s1)) Notice that swapping "s1" and "s2" results in a type error. Nice. Also by choosing different operations one can enforce other properties. Now lets try it out: > test = set True >>>= \x -> > set 'a' >>>= \y -> > ret (x,y) And it is all Haskell 98! Another interesting example of an indexed monad is the continuation monad (I noticed that from Wadler's "Composable Continuations" paper). I hope this helps! -Iavor On 12/17/06, David Roundy |
|||