V. Mimicking Composition of Functions

We have seen a close connection between composition of world remaking functions and the (>>) combinator. In Haskell we write

say_hello >> be_nice

instead of

be_nice.say_hello

but the underlying thought process isn't so very different.

Function composition is associative. That is for type compatible functions f, g, and h

(f.g).h = f.(g.h)

The . operator is enough like that the (>>) and (>>=) combinators that we would like the latter to be associative too. Since (>>=) is the more important, we want to assert something like

(mon1 >>= f) >>= g == 
  mon1 >>= (f >>= g)

to be true. Of course, it is not even syntactically correct: f must be a monad creating function on the left side of the == but a monadic object on the right side.

We can fix this by making f into a monadic object. All it takes is to evaluate f on an argument x. It is easy to find an appropriate x because for any f

f == \x -> f x

Keeping this in mind and realizing that g has nothing to do with that x we can write an associativity axiom for (>>=) this way

(mon >>= f) >>= g == 
   mon >>= (\x -> f x >>= g)

Making use of the fact (>>=) binds from the left and letting m represent an arbitrary monadic object rather than an arbitrary monad, this axiom is usually written

m >>= f >>= g ==
   m >>= (\x -> f x >>= g)

Using the normal definition of (>>) it is possible to prove from this axiom that, for any three type compatible monadic objects, mon1, mon2, and mon3

(mon1 >> mon2) >> mon3 ==
    mon1 >> (mon2 >> mon3)

We will take this similarity with function composition a bit further in Section XII.