[Haskell-cafe] Is my code too complicated?
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