[Haskell-cafe] Stacking monads
andrewcoppin at btinternet.com
Thu Oct 2 15:47:56 EDT 2008
Reid Barton wrote:
> I'll assume for simplicity and concreteness that ResultSet = .
It more or less is. (But with a more complex internal structure, and
correspondingly more complex (>>=) implementation.)
> That's right. The type mismatches are telling you that there's a
> situation you haven't thought about, or at least, haven't told us how
> you want to handle. Suppose run s0 x = Right [s1a, s1b, s1c] and
> run s1a y = Left err, run s1b = Right [s2], run s1c = Left err'. What
> should the overall result of run_and s0 x y be? Somehow you have to
> choose whether it's a Left or a Right, and which error to report in
> the former case.
> For the  monad, there is a natural way to make this choice: it's
> encoded in the function sequence :: Monad m => [m a] -> m [a], where
> in this setting m = Either ErrorType.
Yeah, while testing I accidentally got a definition that typechecks only
because I was using  as a dummy standin for ResultSet. (Rather than
the real implementation.) The sequence function appears to define the
basic functionallity I'm after.
> For your problem, it would
> probably be a good start to write an instance of Traversable for the
> ResultSet monad.
Wuh? What's Traversable?
> In general, one way to make the composition of two
> monads m and n into a monad is to write a function n (m a) -> m (n a);
> this is the sequence method of a Traversable instance for n.
Oh, *that's* Traversable?
Mind you, looking at Data.Traversable, it demands instances for
something called "Foldable" first (plus Functor, which I already happen
(Looking up Foldable immediately meantions something called "Monoid"...
I'm rapidly getting lost here.)
> Then you
> can write join :: m (n (m (n a))) -> m (n a) as
> m (n (m (n a))) --- fmap sequence ---> m (m (n (n a)))
> ------ join ---------> m (n (n a))
> ------ join ---------> m (n a).
Um... OK. Ouch. :-S
More information about the Haskell-Cafe