[Haskell-cafe] Is my code too complicated?

Andrew Coppin andrewcoppin at btinternet.com
Sat Jul 3 09:20:14 EDT 2010


Felipe Lessa wrote:
> Oh, so it is about monad transformers.  =)
>   

> I agree that it gets harder to reason about the code.  In fact,
> sometimes I stack monad transformers in the wrong order.
>
> About monad transformers, I don't really like to use them because they
> can get hairy in some cases, and because they have poor performance in
> other cases.  Yet the decision of using transformers or not should be
> made depending on your particular needs.
>   

In my experience, using more than one monad transformer at once makes 
code utterly incomprehensible. (!) In my humble opinion, this is the 
principle weakness of monads; they allow you to do lots of cool stuff, 
but it's intractibly hard to mix several of them together. (See, for 
example, the combinatorial explosion of class instances in the MTL 
package.) On the few occasions I've attempted to use monad transformers, 
I've often wasted hours staring at a single function call, desperately 
trying to make it type-check. I almost which there was some kind of 
automated tool to tell you which magic combination of library functions 
generates an expression of the correct type. (But there isn't. Hoogle 
will tell you if any existing function vaguely matches what you want, 
but it's no help in suggesting how to combine a dozen functions together 
to get the right type.)

Tangentally, it seems to me that all monads can be described as doing 
zero or more of:
- Invisibly pass state around (and possibly modify it).
- Perform unusual flow control.
- I/O (or some restricted subset of it).
Can anybody think of a monad that does something that doesn't fall under 
one of these categories?

(For example, a parser monad carries around invisible state - the 
current source location, the input being parsed, etc. It also usually 
implements choice - in other words, unusual flow control. And some like 
Parsec allow you to do I/O as well.)

>>  type TextureT = StateT Config
>>
>>  -- Note that this is MonadLib.
>>  -- BaseM m IO corresponds to MonadIO m.
>>  selectTexture :: BaseM m IO => B.ByteString -> TextureT m ()
>>     
>
> "It is the type of functions that may access and modify a state of type Config."
>   

Damn, *I* didn't manage to figure that out, never mind PHP n00bs...



More information about the Haskell-Cafe mailing list