Many of us don\'t have a background on functional programming, and much less on category theory algebra. So let\'s suppose that we need and therefore create a generic type like<
You should be on the lookout if you end up writing any operations that have signatures that look like any of these—or just as importantly, if you have a number of functions that can be refactored to use them:
----- Functor -----
-- Apply a one-place function "inside" `MySomething`.
fmap :: (a -> b) -> MySomething a -> MySomething b
----- Applicative -----
-- Apply an n-place function to the appropriate number and types of
-- `MySomething`s:
lift :: (a -> ... -> z) -> MySomething a -> ... -> MySomething z
-- Combine multiple `MySomething`s into just one that contains the data of all
-- them, combined in some way. It doesn't need to be a pair—it could be any
-- record type.
pair :: MySomething a -> ... -> MySomething z -> MySomething (a, ..., z)
-- Some of your things act like functions, and others like their arguments.
apply :: MySomething (a -> b) -> MySomething a -> MySomething b
-- You can turn any unadorned value into a `MySomething` parametrized by
-- the type
pure :: a -> MySomething a
-- There is some "basic" constant MySomething out of which you can build
-- any other one using `fmap`.
unit :: MySomething ()
----- Monad -----
bind :: MySomething a -> (a -> MySomething b) -> MySomething b
join :: MySomething (MySomething a) -> MySomething a
----- Traversable -----
traverse :: Applicative f => (a -> f b) -> MySomething a -> f (MySomething b)
sequence :: Applicative f => MySomething (f a) -> f (MySomething a)
Note four things:
Applicative
may be less famous than Monad
, yet it's a very important and valuable class—arguably the centerpiece of the API! A lot of things that people originally used Monad
for actually only require Applicative
. It's a good practice not to use Monad
if Applicative
will do.Traversable
—a lot of functions that were originally written for Monad
(sequence
, mapM
) in fact only require Traversable
+ Applicative
.Monad
is by first discovering that it's an Applicative
and then asking whether it's also a Monad
.