For monads like StateT, WriterT, ReaderT, the order doesn't matter (except
perhaps for some pesky performance details). However, for monad transformers
like ErrorT or ListT, the order _does_ matter.

The code you have there is perfectly fine, sometimes the added generality
can be quite handy (especially if you have your own MonadState'esk type
classes).
The two major drawbacks to this approach (that I can think of off the top of
my head) are:
1) Rather large and complicated contexts on quite a few of your functions
2) Can lead to nearly indecypherable error messages

Personally, I try to avoid multiparameter typeclasses whenever possible;
I've found them to be more trouble than they are worth.

My advice would be to leave the code general if the code actually does
something general (it actually has more than one use case) and give the code
a fixed signature if the code really one has just one purpose (even if ghci
can infer a general type for you).
This is just a personal preference, but it seems to work well for me :)

- Job


On Mon, Aug 9, 2010 at 3:05 PM, aditya siram <aditya.si...@gmail.com> wrote:

> Hi all,
> I was experimenting with monad transformers and realized that the stacking
> order of the monads can remain unknown until it is used. Take for example
> the following code:
>
> import "mtl" Control.Monad.State
> import "mtl" Control.Monad.Writer
> import "mtl" Control.Monad.Identity
>
> test :: (MonadWriter [Char] m, Num t, MonadState t m) => m ()
> test = do
>      put 1
>      tell "hello"
>
> main = do
>      x <- return $ runIdentity $ runStateT (runWriterT test) 1 -- test ::
> WriterT String (StateT Int Identity)
>      y <- return $ runIdentity $ runWriterT $ runStateT test 1 -- test ::
> StateT Int (WriterT String Identity)
>      z <- runWriterT $ runStateT test 1                        -- test ::
> StateT Int (WriterT String IO) (((), Int), String)
>      print x
>      print y
>      print z
>
> *Main> main
> (((),"hello"),1)
> (((),1),"hello")
> (((),1),"hello")
>
> Until test is called in 'main' we don't know the order of monads. In fact
> even the base monad is not know. All we know is that it uses the State and
> Writer monad. In each call to 'test' in main we can determine the stacking
> order and the base monad yielding different results. This seems to be a more
> flexible way of using monad transformers but I haven't seen this in code
> before so is there anything wrong with this style?
>
> -deech
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to