Sjoerd Visscher sjoerd at w3future.com
Wed Jul 15 08:34:24 EDT 2009

```Actually, you can make a joinInner for the State monad. However, it
does not allow the inner function (h) to change the state, because how
state is threaded through a monad N is different for each N.

i :: (Monad n) => (a -> State s b) -> (b -> n c) -> (c -> State s d) -
> (a -> State s (n d))
i f g h = joinInnerState . liftM (liftM h . g) . f

joinInnerState :: Monad n => State s (n (State s a)) -> State s (n a)
joinInnerState (State g) = State \$ joinInnerAsReader . g
where
joinInnerAsReader (n, s) = (liftM (fst . (\$ s) . runState) n, s)

joinInner is the only one of the 3 that works, because the outer M
gives you an initial state to work with.

Sjoerd

On Jul 10, 2009, at 11:25 PM, Job Vranish wrote:

> 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
> 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)
>
>
> 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?
> _______________________________________________
>
>
>
> _______________________________________________

--
Sjoerd Visscher
sjoerd at w3future.com

-------------- next part --------------
An HTML attachment was scrubbed...