Hello,<br><br>I was wondering if it's possible to stack a runtime-known amount of<br>monads on top of each other. Let me illustrate. Assume I have a monad<br>that can consume data and expects as starting parameter an action of the
<br>underlying monad to use this data (call it produce at the lower level<br>monad).<br><br>Now one could imagine stacking one of these consumers on top of the<br>other, as can be seen below. However I can not choose at runtime how
<br>many I want to stack. Is there any solution for this?<br><br>Regards,<br>Christophe<br><br><br>------------------------------<div id="mb_0">--------------------------------------------------<br>{-# OPTIONS_GHC -fglasgow-exts #-}
<br>module Main where<br>import Control.Monad<br>import Control.Monad.Identity<br>import Control.Monad.State<br>import Control.Monad.Trans<br><br>data Action e m = Action {<br> &nbsp;produce :: e -&gt; m ()<br>}<br><br>newtype SequencerT e m a = SequencerT (StateT (Action e m) m a)
<br> &nbsp;deriving (Functor, Monad, MonadIO)<br><br>newtype Sequencer e a = Sequencer (SequencerT e Identity a)<br> &nbsp;deriving (Functor, Monad, MonadSequencer e)<br><br>instance MonadTrans (SequencerT e) where<br> &nbsp;lift = SequencerT . lift
<br><br>class Monad m =&gt; MonadSequencer e m | m -&gt; e where<br> &nbsp;consume &nbsp; &nbsp; :: e -&gt; m ()<br><br>instance Monad m =&gt; MonadSequencer e (SequencerT e m) where<br> &nbsp;consume x &nbsp; = SequencerT $ do<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;s &lt;- get
<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lift . (produce s) $ x<br><br>evalSequencerT (SequencerT s) action =<br> &nbsp;evalStateT s action<br>evalSequencer (Sequencer s) inputs action =<br> &nbsp;evalSequencerT s action<br><br>runSequencerT (SequencerT s) action =
<br> &nbsp;runStateT s action<br>runSequencer (Sequencer s) action =<br> &nbsp;runSequencerT s action<br><br>main :: IO () =<br> &nbsp;evalSequencerT<br> &nbsp; &nbsp;(evalSequencerT<br> &nbsp; &nbsp; &nbsp;(consume 1 &gt;&gt; consume 2 &gt;&gt; consume 3)<br> &nbsp; &nbsp; &nbsp;(Action{produce = \x -&gt; if x &gt; 1 then consume x else liftIO . print $ (&quot;A&quot; ++ show x)}))
<br> &nbsp; &nbsp;(Action{produce = print . (&quot;B&quot; ++) . show })<br><br><br>--<br>Christophe Poucet<br>Ph.D. Student<br>Phone:+32 16 28 87 20<br>E-mail: <span style="text-decoration: underline;">---</span><a onclick="return top.js.OpenExtLink(window,event,this)" href="mailto:Christophe.Poucet@imec.be">
</a><br>IMEC vzw  Register of Legal Entities Leuven VAT BE 0425.260.668  Kapeldreef 75, B-3001 Leuven, Belgium  <a onclick="return top.js.OpenExtLink(window,event,this)" href="http://www.imec.be/" target="_blank">www.imec.be
</a><br>*****DISCLAIMER*****<br>This e-mail and/or its attachments may contain confidential information. It is intended solely for the intended addressee(s).<br>Any
use of the information contained herein by other persons is prohibited.
IMEC vzw does not accept any liability for the contents of this e-mail
and/or its attachments.<br>**********<br></div>