[Haskell-beginners] stream of monadic calculations

Nick Vanderweit nick.vanderweit at gmail.com
Tue Oct 2 21:14:12 CEST 2012


Let's look at the analogous case:

let a'  = f a
      a'' = g a'
     a''' = h a''
  in <something to do with a'''>

Here, the way we would shorten "apply f, then apply g, then apply h" is using 
the function composition operator, (.), whose type signature is:

(.) :: (b -> c) -> (a -> b) -> a -> c

So instead of the above, we could say:
let a''' = h . g . f $ a

Similarly, you have some functions:
f :: a -> m b
g :: b -> m c

for some monad m. And what you'd like to do is, in some sense, to compose 
these, to get:

g . f :: a -> m c

But you can't exactly do that with the Prelude composition operator; the types 
are wrong. Fortunately, smart people have already thought about how to 
generally compose function-like things. The way you do this in a monad-specific 
way is to use the (<=<) operator from Control.Monad, whose signature is:

(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c

And so that's really what you want: h <=< g <=< f $ a.

More generally, this whole idea of composing things that are similar to 
functions is encapsulated by the notion of a category, and this can be viewed 
as a specific case of using the composition operator from Control.Category. In 
this case, the function-like things (called "arrows" or "morphisms") being 
composed are the so-called Kleisli arrows, which are really the functions 
you're manipulating here, f :: a -> m b.



Nick


On Tuesday, October 02, 2012 10:12:44 AM Christopher Howard wrote:
> Say I've got a stream of monadic calculations, like so:
> 
> code:
> --------
> do a' <- f a
>    a'' <- g a'
>    a''' <- h a''
>    return a'''
> --------
> 
> There is a cleaner way to do that, yes? (Without using all the tick marks?)



More information about the Beginners mailing list