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

Jake McArthur jake.mcarthur at gmail.com
Thu Jun 18 09:54:31 EDT 2009

```Jake McArthur wrote:
> Generally, you can transform anything of the form:
>
>     baz x1 = a =<< b =<< ... =<< z x1
>
> into:
>
>     baz = a <=< b <=< ... <=< z

I was just looking through the source for the recently announced Hyena
library and decided to give a more concrete example from a real-world
project. Consider this function from the project's Data.Enumerator
module[1]:

compose enum1 enum2 f initSeed = enum1 f1 (Right initSeed) >>= k
where
f1 (Right seed) bs = ...
k (Right seed) = ...

First, I would flip the `(>>=)` into a `(=<<)` (and I will ignore the
`where` portion of the function from now on):

compose enum1 enum2 f initSeed = k =<< enum1 f1 (Right initSeed)

Next, transform the `(=<<)` into a `(<=<)`:

compose enum1 enum2 f initSeed = k <=< enum1 f1 \$ Right initSeed

We can "move" the `(\$)` to the right by using `(.)`:

compose enum1 enum2 f initSeed = k <=< enum1 f1 . Right \$ initSeed

Finally, we can drop the `initSeed` from both sides:

compose enum1 enum2 f = k <=< enum1 f1 . Right

I didn't test that my transformation preserved the semantics of the
function or even that the type is still the same, but even if it's wrong
it should give you the idea.

- Jake

[1]