I'm digging deeper into Yesod's monads, and have encountered MonadBaseControl. I took a look at the hackage doc, and got lost. Could someone tell me the problem it is trying to solve?

share|improve this question
3  
It's actually from monad-control, the package description there says "This package defines the type class MonadBaseControl, a subset of MonadBase into which generic control operations such as catch can be lifted from IO or any other base monad." Doesn't tell me which problem it's meant to solve, unfortunately. – Daniel Fischer Jul 28 '12 at 0:30
2  
Take a look at [lifted-base](hackage.haskell.org/package/lifted-base). It provides lifted versions of many standard IO-based functions. For example, using MonadBaseControl you can write a piece of code that runs inside a complex IO-based monad stack, and call fork inside that stack, transferring whatever context the monad has into the forked thread as well. – Petr Pudlák May 13 '14 at 19:26
up vote 14 down vote accepted

It comes from the package monad-control, and is one of a pair of type classes (the other one being MonadTransControl) that enhance MonadBase (resp. MonadTrans) by supporting an alternative liftBase (resp. lift) operation for monads that implement it. This enhanced version no longer takes a simple action in the absolute base monad (resp. immediate base monad), but instead takes a function that gets the base monad's (resp. monad transformer's) whole state at that point as its only parameter and returns the aforementioned action.

As the package documentation states, this enhancement, along with the rest of the contents of these type classes, allow you to lift functions like catch, alloca, and forkIO from the absolute base monad (resp. immediate base monad), which is not possible with the simpler scheme present in MonadBase (resp. MonadTrans) because the latter pair do not allow you to lift the arguments of a function, just the results, while the approach taken by monad-control allows both.

As a result, the set of monads (resp. monad transformers) that can be used with MonadBaseControl (resp. MonadTransControl) is a strict subset of the set of monads that can be used with MonadBase (resp. MonadTrans), but the former groups are much more powerful than the latter for the same reason.

share|improve this answer

Michael Snoyman actually wrote a small tutorial on monad-control: http://www.yesodweb.com/book/monad-control

The gist of that article might be the following:

Imagine you have this piece of code:

withMyFile :: (Handle -> IO a) -> IO a
withMyFile = withFile "test.txt" WriteMode

You can apply withMyFile to any function of the type Handle -> IO a and get a nice IO a value. However, what if you have a function of the type Handle -> ErrorT MyError IO a and want to get a value of type ErrorT MyError IO a? Well, basically, you will have to modify withMyFile in order to incorporate a lot of wrapping/unwrapping. MonadBaseControl allows you to somewhat 'lift' functions like withMyFile to certain monad transfromers which allows unwrapping ("running"). Thus, resulting code looks like this:

useMyFileError :: (Handle -> ErrorT MyError IO ()) -> ErrorT MyError IO ()
useMyFileError func = control $ \run -> withMyFile $ run . func
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.