[Haskell-cafe] Stacking monads
Andrew Coppin
andrewcoppin at btinternet.com
Fri Oct 3 13:39:08 EDT 2008
David Menendez wrote:
> On Thu, Oct 2, 2008 at 3:40 PM, Andrew Coppin
> <andrewcoppin at btinternet.com> wrote:
>
>> David Menendez wrote:
>>
>>> You could try using an exception monad transformer here
>>>
>> I thought I already was?
>>
>
> No, a monad transformer is a type constructor that takes a monad as an
> argument and produces another monad. So, (ErrorT ErrorType) is a monad
> transformer, and (ErrorT ErrorType m) is a monad, for any monad m.
>
Right, OK.
> If you look at the type you were using, you see that it breaks down into
> (Either ErrorType) (ResultSet State), where Either ErrorType :: * -> *
> and ResultSet State :: *. Thus, the monad is Either ErrorType. The
> fact that ResultSet is also a monad isn't enough to give you an
> equivalent to (>>=), without one of the functions below.
>
OK, that makes sense.
>> Uh... what's Applicative? (I had a look at Control.Applicative, but it just
>> tells me that it's "a strong lax monoidal functor". Which isn't very
>> helpful, obviously.)
>>
>
> Applicative is a class of functors that are between Functor and Monad
> in terms of capabilities. Instead of (>>=), they have an operation
> (<*>) :: f (a -> b) -> f a -> f b, which generalizes Control.Monad.ap.
>
(As an aside, Control.Monad.ap is not a function I've ever heard of. It
seems simple enough, but what an unfortunate name...!)
> The nice thing about Applicative functors is that they compose.
>
> With monads, you can't make (Comp m1 m2) a monad without a function
> analogous to inner, outer, or swap.
>
So I see. I'm still not convinced that Applicative helps me in any way
though...
> From your code examples, it isn't clear to me that applicative
> functors are powerful enough, but I can't really say without knowing
> what you're trying to do.
The whole list-style "multiple inputs/multiple outputs" trip, basically.
> The fact that the functions you gave take a
> state as an argument and return a state suggests that things could be
> refactored further.
>
If you look at run_or, you'll see that this is _not_ a simple state
monad, as in that function I run two actions starting from _the same_
initial state - something which, AFAIK, is impossible (or at least very
awkward) with a state monad.
Really, it's a function that takes a state and generates a new state,
but it may also happen to generate *multiple* new states. It also
consumes a Foo or two in the process.
More information about the Haskell-Cafe
mailing list