On Mon, Jun 28, 2004 at 02:59:39PM +0100, Graham Klyne wrote:
> Is there a function that switches monadic layering?
> 
>     f :: (Monad m1,Monad m2) => m1 (m2 a) -> m2 (m1 a)
> 
> Does this even make sense in the general case?  I'm thinking along the 
> lines of a generalization of sequence to non-list monads.

Such a function is called a distributive law of m1 over m2 if it satisfies
the following equations (subscripts added for readability):

        f . return_1 = liftM_2 return_1
        f . liftM_1 return_2 = return_2
        f . join_1 = liftM_2 join_1 . f . liftM_1 f
        f . liftM_1 join_2 = join_2 . liftM_2 f . f

The composition m2.m1 can be made a monad in a standard way:

        return = return_2 . return_1
        join = liftM_2 join_1 . join_2 . liftM_2 f

if and only if such a distributive law exists.  See section 9.2 of
"Toposes, Triples and Theories", by Michael Barr and Charles Wells,
online at

        http://www.cwru.edu/artsci/math/wells/pub/ttt.html

("triple" is another name for a monad)

> [...], and sequence does 
> for the List monad what I am seeking to generalize:
> 
>    sequence :: [m a] -> m [a]

Yes, it's a distributive law of [] over m, but only if m is a
commutative monad (lists are so sequential).

Some more distributive laws:

* the exception monad distributes over any other monad:

        either (return . Left) (liftM Right)
                :: Monad m => Either x (m a) -> m (Either x a)

* so does the writer monad:

        uncurry (liftM . (,)) :: (Monoid w, Monad m) => (w, m a) -> m (w,a)

* any monad distributes over the reader monad:

        flip (liftM . flip ($)) :: Monad m => m (r -> a) -> r -> m a
_______________________________________________
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to