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