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

Thu Jun 18 10:02:55 EDT 2009

```What is enum2 doing in all of this - it appears to be ignored.

2009/6/18 Jake McArthur <jake.mcarthur at gmail.com>:
> 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]