Once again, the advantage of defining a class like this is
that it allows us to define generic operators, this time
for arbitrary instances of the "Monad" class. The code
at the top of this slide shows a definition for the Kleisli
composition operator. (Advocates of the monad laws will be
able to derive a shorter version by eliminating the trailing
return; we use the version here because it is more symmetric.)
Left to its own devices, a Haskell system will automatically
infer the type of the (@) operator shown in the middle of the
slide. Note that this type indicates that the definition will
work for all monads.
In fact, to make monadic programming more comfortable, Haskell
provides special syntax for it---the so-called do notation
shown at the bottom of this slide---which is defined in terms
of a translation using the operators of the "Monad" class.
Is it reasonable to use overloading for the monad operators
instead of more explicit parameterization? I think so, and
part of that is because I have never come across a practical
situation where I wanted to use two different monad structures
on a single parameterized datatype.