<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>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.</div><div><br></div><div><div>i :: (Monad n) =&gt; (a -&gt; State s b) -&gt; (b -&gt; n c) -&gt; (c -&gt; State s d) -&gt; (a -&gt; State s (n d))</div><div>i f g h = joinInnerState . liftM (liftM h . g) . f</div><div><br></div><div>joinInnerState :: Monad n =&gt; State s (n (State s a)) -&gt; State s (n a)</div><div>joinInnerState (State g) = State $ joinInnerAsReader . g</div><div>&nbsp;&nbsp;where</div><div>&nbsp;&nbsp; &nbsp;joinInnerAsReader (n, s) = (liftM (fst . ($ s) . runState) n, s)</div></div><div><br></div><div>joinInner is the only one of the 3 that works, because the outer M gives you an initial state to work with.</div><div><br></div><div>Sjoerd</div><br><div><div>On Jul 10, 2009, at 11:25 PM, Job Vranish wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">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. <br>Maybe someday Haskell will infer valid joinInner/joinOuter for simple cases :D<br> Thanks for you help. I'll definitely have to see if I can find that paper.<br><br>- Job Vranish<br><br><div class="gmail_quote">On Fri, Jul 10, 2009 at 3:09 PM, Edward Kmett <span dir="ltr">&lt;<a href="mailto:ekmett@gmail.com">ekmett@gmail.com</a>&gt;</span> wrote:<br> <blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div>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.</div> <div>&nbsp;</div> <div>What I would look for is a function of the form of one of:</div> <div>&nbsp;</div> <div>distribute :: N (M a) -&gt; M (N a)</div> <div>joinInner :: M (N (M a)) -&gt; M (N a)</div> <div>joinOuter :: N (M (N a)) -&gt; M (N a)<br><br>that holds for your partiular monads M and N.</div> <div>&nbsp;</div> <div>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.</div> <div>&nbsp;</div> <div>-Edward Kmett</div> <div>&nbsp;</div> <div class="gmail_quote"><div><div></div><div class="h5">On Fri, Jul 10, 2009 at 11:34 AM, Job Vranish <span dir="ltr">&lt;<a href="mailto:jvranish@gmail.com" target="_blank">jvranish@gmail.com</a>&gt;</span> wrote:<br> </div></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0px 0px 0px 0.8ex; padding-left: 1ex;"><div><div></div><div class="h5">I'm trying to make a function that uses another monadic function inside a preexisting monad, and I'm having trouble.<br> Basically my problem boils down to this. I have three monadic functions with the following types:<br>f :: A -&gt; M B<br>g :: B -&gt; N C<br>h :: C -&gt; M D<br>(M and N are in the monad class)<br>I want a function i where <br> i :: A -&gt; M (N D)<br><br>the best I can come up with is:<br>i :: A -&gt; M (N (M D))<br>i a = liftM (liftM h) =&lt;&lt; (return . g) (f a)<br><br>I'm starting to feel pretty sure that what I'm going for is impossible. Is this the case? <br> </div></div> _______________________________________________<br>Haskell-Cafe mailing list<br><a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br><a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br> <br></blockquote></div><br> </blockquote></div><br> _______________________________________________<br>Haskell-Cafe mailing list<br><a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>http://www.haskell.org/mailman/listinfo/haskell-cafe<br></blockquote></div><br><div apple-content-edited="true"> <span class="Apple-style-span" style="font-size: 12px; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>--</div><div>Sjoerd Visscher</div><div><a href="mailto:sjoerd@w3future.com">sjoerd@w3future.com</a></div><div><br></div></div></span><br class="Apple-interchange-newline"> </div><br></body></html>