[Haskell-cafe] Monad-control rant

Mikhail Vorozhtsov mikhail.vorozhtsov at gmail.com
Tue Jan 10 15:54:38 CET 2012

On 01/10/2012 12:17 AM, Edward Z. Yang wrote:
> Hello Mikhail,
> (Apologies for reviving a two month old thread). Have you put some thought into
> whether or not these extra classes generalize in a way that is not /quite/ as
> general as MonadBaseControl (so as to give you the power you need) but still
> allow you to implement the functionality you are looking for? I'm not sure but
> it seems something along the lines of unwind-protect ala Scheme might be
> sufficient.
I'm not sure I'm following you. The problem with MonadBaseControl is 
that it is /not/ general enough. It assumes that you can eject/inject 
all the stacked effects as a value of some data type. Which works fine 
for the standard transformers because they are /implemented/ this way. 
But not for monads that are implemented in operational style, as 
interpreters, because the interpreter state cannot be internalized. This 
particular implementation bias causes additional issues when the lifted 
operation is not fully suited for ejecting/injecting. For example the 
`Control.Exception.finally` (or unwind-protect), where we can neither 
inject (at least properly) the effects into nor eject them from the 
finalizer. That's why I think that the whole "lift operations from the 
bottom" approach is wrong (the original goal was to lift 
`Control.Exception`). The right way would be to capture the control 
semantics of IO as a set of type classes[1] and then implement the 
general versions of the operations you want to lift. That's what I tried 
to do with the monad-abord-fd package.

Hopefully this makes sense to you.

[1] Which turn out to be quite general: MonadAbort/Recover/Finally are 
just a twist of MonadZero/MonadPlus; MonadMask is expectedly more 
specific, but permits a nice no-op implementation.

More information about the Haskell-Cafe mailing list