The compositional point of view is actually enlightening in itself.
Monads can be considered as part of a "funky composition" between functions of the form a -> Mb
. You can compose f : a -> M b
and g: b -> M c
into something a -> M c
through monad operations (just bind the return value of f
to g
).
This turns the arrows of the form a -> M b
category arrows, called the Claysley category M
If M
were not a monad, but just a functor, you could compose fmap g
and f
into something (fmap g) . f :: a -> M (M c)
(fmap g) . f :: a -> M (M c)
. Monads have join :: M (M a) -> M a
, which I allow you to define as a (simple and useful) exercise using only monad operations (for mathematicians, join
usually part of the monad definition). Then join . (fmap g) . f
join . (fmap g) . f
join . (fmap g) . f
gives a composition for the Claysley category.
Thus, you can see the whole funky monadic composition inside
join
,
join
represents side effects composition: for
IO
it exposes effects sequentially, for
List
it combines lists, for
Maybe
it โstops the calculationโ when the result is
Nothing
, for
Writer
it writes sequentially, for
State
it sequentially performs operations on the state, etc. It can be thought of as an "overloaded semicolon" if you know C-like languages. It is very instructive to think of monads in this way.
Of course Dan Piponi explains this a lot better than I do, and here is his post that you can find out: http://blog.sigfpe.com/2006/06/monads-kleisli-arrows-comonads-and.html
source share