[Haskell-cafe] Re: Problems with nested Monads

John Lato jwlato at gmail.com
Wed Jul 15 20:05:39 EDT 2009

If M is a monad transformer (e.g. StateT) and able to be parameterised
over an arbitrary monad, you can do something related, which may
actually be more useful to you.

Given the definition of StateT from mtl:

newtype StateT s m a = StateT {
runStateT :: s -> m (a, s)

you could define this join-like function:

join2 :: (Monad n) => n (StateT s n a) -> StateT s n a
join2 m = StateT (\state -> m >>= flip runStateT state)

(I don't know a good name for this function; it's called "joinIM" in iteratee)

Perhaps this would apply to your situation?

John Lato

> Message: 18
> Date: Fri, 10 Jul 2009 17:25:55 -0400
> From: Job Vranish <jvranish at gmail.com>
> Subject: Re: [Haskell-cafe] Problems with nested Monads
> To: Edward Kmett <ekmett at gmail.com>
> Cc: Haskell Cafe mailing list <haskell-cafe at haskell.org>
> Message-ID:
>        <ed4cefb50907101425w118990e2x5d6585582157e08f at mail.gmail.com>
> Content-Type: text/plain; charset="iso-8859-1"
> Yeah, I think the problem with my case is that while M is a specific monad
> (essentially StateT), N can be an arbitrary monad, which I think destroys my
> changes of making a valid joinInner/joinOuter/distribute.
> Maybe someday Haskell will infer valid joinInner/joinOuter for simple cases
> :D
> Thanks for you help. I'll definitely have to see if I can find that paper.
> - Job Vranish
> On Fri, Jul 10, 2009 at 3:09 PM, Edward Kmett <ekmett at gmail.com> wrote:
>> The problem you have is that monad composition isn't defined in general.
>> You would need some form of distributive law either for your monads in
>> general, or for your particular monads wrapped around this particular kind
>> of value.
>> What I would look for is a function of the form of one of:
>> distribute :: N (M a) -> M (N a)
>> joinInner :: M (N (M a)) -> M (N a)
>> joinOuter :: N (M (N a)) -> M (N a)
>> that holds for your partiular monads M and N.
>> IIRC Mark P. Jones wrote a paper or a lib back around '93 that used these
>> forms of distributive laws to derive monads from the composition of a monad
>> and a pointed endofunctor.
>> -Edward Kmett
>> On Fri, Jul 10, 2009 at 11:34 AM, Job Vranish <jvranish at gmail.com> wrote:
>>> I'm trying to make a function that uses another monadic function inside a
>>> preexisting monad, and I'm having trouble.
>>> Basically my problem boils down to this. I have three monadic functions
>>> with the following types:
>>> f :: A -> M B
>>> g :: B -> N C
>>> h :: C -> M D
>>> (M and N are in the monad class)
>>> I want a function i where
>>> i :: A -> M (N D)
>>> the best I can come up with is:
>>> i :: A -> M (N (M D))
>>> i a = liftM (liftM h) =<< (return . g) (f a)
>>> I'm starting to feel pretty sure that what I'm going for is impossible. Is
>>> this the case?
>>> _______________________________________________
>>> Haskell-Cafe mailing list
>>> Haskell-Cafe at haskell.org
>>> http://www.haskell.org/mailman/listinfo/haskell-cafe

More information about the Haskell-Cafe mailing list