2006/8/11, Stefan Aeschbacher &lt;<a href="mailto:haskell@aeschbacher.ch" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">haskell@aeschbacher.ch</a>&gt;:<div><span class="gmail_quote"></span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

Hi<br><br>I'm trying to understand Monad Transformers. The code below works as<br>expected but I have the following questions:<br> - why can I use liftIO but not lift in the doSomething function?</blockquote><div><br>I will first try to explain why it is not possible to use lift.
<br><br>Short version : In the definition of MyM<br><br><blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote">type MyM a = WriterT [Entry] (ReaderT MyData IO) a
<br></blockquote><br>WriterT is parameterized with a *fixed* monad type, namely (ReaderT MyData IO). <br>But in order to be able to instantiate MonadTrans and defining lift,&nbsp; this value has to be a parameter. <br>The parameter should then take on different values, depending on which monad to lift.
<br>I.e. MyM a = ... should instead look like MyM m a = ... <br><br>Longer version:<br><br>Looking at the definition of MonadTrans and lift one sees that lift, <br>given a monadic value, produces a transformed version of this monad.
<br><br>class MonadTrans t where<br>&nbsp; lift :: Monad m =&gt; m a -&gt; t m a
<br><br>In the case with the 'doSomething function', we wish to lift an action of type (IO ()) into MyM. <br><br>So, what is the generell type of 'lift (some IO () action)' , e.g lift (putStr &quot;hello&quot;) ? <br><br>

Examining the definition of lift above (or using :t&nbsp; ) , concludes that : <br><br>lift (putStr &quot;hello&quot;) :: MonadTrans t =&gt; t IO (). <br><br>Due to the type of 'doSomething'&nbsp; (doSomething :: MyM Int)<br>the monad transformer 't' should have type MyM,&nbsp; making the result of the lift operation MyM IO ().
<br><br>However, this is where it fails. According to the definition of MyM it canīt be parameterised <br>with more than one type (not with both IO and ()). <br><br>But, a monad transformer MUST have kind ((* -&gt; *) -&gt; * -&gt; *) in order to
<br>be able to create a valid return type for lift. So even if we wished to<br>write our own instance for MonadTrans MyM, it wouldn't be possible.<br><br>Compare with the following example which on the other hand does work with lift.
<br><br>type MyM2 m a = WriterT [Entry] m a<br><br>doSomethingElse :: MyM2 IO Int<br>doSomethingElse = do<br>&nbsp; lift $ putStrLn &quot;hello&quot;<br>&nbsp; return 2<br><br>Now, MyM2 has the right kind. And since (WriterT w) ,for any Monoid w, instantiates
<br>the MonadTrans class, it is possible to use the lift function to produce a value of type MyM2 IO ().<br><br>So, why does liftIO work ? Consider the definition of MonadIO :<br><br>class (Monad m) =&gt; MonadIO m where
<br>
&nbsp; liftIO :: IO a -&gt; m a<br><br>The monad that should embed the IO action (m above) has kind (* -&gt; *). <br>This makes an instance for MyM possible. Because MyM is a synonym for a WriterT monad,<br>an instance for this is allready defined in the 
Controll.Monad.WriterT module:<br><br>instance (Monoid w, MonadIO m) =&gt; MonadIO (WriterT w m) where<br>&nbsp;&nbsp;&nbsp; liftIO = lift . liftIO<br>&nbsp;&nbsp;&nbsp; <br>Actually it also requires that the inner monad, i.e. ReaderT in this case, also instantiates the MonadIO, which luckily it does :)
<br><br>Looking at this, It's not hard to get lost in the jungle of monads :)<br>From my own experience (which isn't long),&nbsp; I think the most effective way of learning<br>is trying to write all definitions and instances by you're own, getting a feeling for what is
<br>really going on..<br><br>Hope that this will be of any help!<br><br><blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote">&nbsp;- why is there no liftSTM function?
</blockquote></div><div><br>Don't know about that, but someone else sure does..<br><br>Regards<br>/Joel<br></div></div><br>