Dynamically stackable monads

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Dynamically stackable monads

Christophe Poucet
Hello,

I was wondering if it's possible to stack a runtime-known amount of
monads on top of each other. Let me illustrate. Assume I have a monad
that can consume data and expects as starting parameter an action of the
underlying monad to use this data (call it produce at the lower level
monad).

Now one could imagine stacking one of these consumers on top of the
other, as can be seen below. However I can not choose at runtime how
many I want to stack. Is there any solution for this?

Regards,
Christophe


------------------------------
--------------------------------------------------
{-# OPTIONS_GHC -fglasgow-exts #-}
module Main where
import Control.Monad
import Control.Monad.Identity
import Control.Monad.State
import Control.Monad.Trans

data Action e m = Action {
 produce :: e -> m ()
}

newtype SequencerT e m a = SequencerT (StateT (Action e m) m a)
 deriving (Functor, Monad, MonadIO)

newtype Sequencer e a = Sequencer (SequencerT e Identity a)
 deriving (Functor, Monad, MonadSequencer e)

instance MonadTrans (SequencerT e) where
 lift = SequencerT . lift

class Monad m => MonadSequencer e m | m -> e where
 consume     :: e -> m ()

instance Monad m => MonadSequencer e (SequencerT e m) where
 consume x   = SequencerT $ do
                 s <- get
                 lift . (produce s) $ x

evalSequencerT (SequencerT s) action =
 evalStateT s action
evalSequencer (Sequencer s) inputs action =
 evalSequencerT s action

runSequencerT (SequencerT s) action =
 runStateT s action
runSequencer (Sequencer s) action =
 runSequencerT s action

main :: IO () =
 evalSequencerT
   (evalSequencerT
     (consume 1 >> consume 2 >> consume 3)
     (Action{produce = \x -> if x > 1 then consume x else liftIO . print $ ("A" ++ show x)}))
   (Action{produce = print . ("B" ++) . show })


--
Christophe Poucet
Ph.D. Student
Phone:+32 16 28 87 20
E-mail: ---[hidden email]
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
*****DISCLAIMER*****
This e-mail and/or its attachments may contain confidential information. It is intended solely for the intended addressee(s).
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.
**********

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe