# [Haskell-cafe] Confusion on the third monad law when using lambda abstractions

Jake McArthur jake.mcarthur at gmail.com
Thu Jun 18 09:34:45 EDT 2009

```Hans van Thiel wrote:
> The only place I've ever seen Kleisli composition, or its flip, used is
> in demonstrating the monad laws. Yet it is so elegant and, even having
> its own name, it must have some practical use. Do you, or anybody else,
> have some pointers?

I only just started finding places to use it myself, admittedly, but I
now think it has common use and it fairly easy to spot. I'll take it
slow, if not for you, as you seem to have a grasp on what these
this form:

foo x = a \$ b \$ c \$ d \$ e \$ f x

The obvious thing to do here is to simply drop the `x` from both sides
by using `(.)` instead of `(\$)`:

==>

foo x = a . b . c . d . e . f \$ x

==>

foo = a . b . c . d . e . f

Now, consider this:

bar x = a =<< b =<< c =<< d =<< e =<< f x

If you compare that to the original version of `foo` above, you see that
it is similar. In fact, looking at the types for `(\$)` and `(=<<)`:

(\$)   ::            (a ->   b) -> (  a ->   b)
(=<<) :: Monad m => (a -> m b) -> (m a -> m b)

So, `(=<<)` is just like `(\$)` except for the information carried along

Anyway, the "obvious" thing to do is to drop the `x` from both sides of
the definition for `bar`. To do that with `foo` earlier, we had to
substitute `(\$)` with `(.)`. What we are looking for is an equivalent

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

So we now can do this:

==>

bar x = a <=< b <=< c <=< d <=< e <=< f \$ x

==>

bar = a <=< b <=< c <=< d <=< e <=< f

And we're done.

Generally, you can transform anything of the form:

baz x1 = a =<< b =<< ... =<< z x1

into:

baz = a <=< b <=< ... <=< z

If you aren't already using `(=<<)` much more than `(>>=)` or
do-notation then you will have a harder time finding opportunities to
use `(<=<)` because only `(=<<)` has the same flow as function
application, which allows your mind to play the appropriate association
games. I suppose you could also replace `(>>=)` with `(>>>)`, but this
would likely require more mental adjustment than replacing `(=<<)` with
`(<=<)`.

- Jake
```