[Haskell-cafe] More Flexible Monad Transformer OR Bad Coding Style

Job Vranish job.vranish at gmail.com
Mon Aug 9 15:42:41 EDT 2010


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.siram at 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 at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100809/ea353352/attachment.html


More information about the Haskell-Cafe mailing list