(En) Comparision of functor, applicative and monad
Outline
We will dicuss about the relationship between each type class (monoid, functor, applicative, and monad). You can discover more with the links to the relevant videos as bellow (English videos coming soon).
Review about type signature of ($)
, (<>)
, (<$>)
, (<*>)
, (>>=)
or flip bind (=<<)
- Function application
($) :: (a -> b) -> a -> b
let’s say that function f
has signature f :: a -> b
, we have these equivalent transformations as below
f :: a -> b
f a :: b -- apply f to a
(a -> b) -> a :: b -- replace f with (a -> b)
($) :: (a -> b) -> a ->b
In fact, we see lots of block of code as below
print $ show a
- Monoid (mappend function)
(<>) :: Semigroup m => m -> m -> m
We see that (<>)
or mappend
receive 2 params which have the same type (structure), and return the result which also keep the original structure (type)
putStrLn $ "hello" <> " " <> "world!"
- Functor (fmap function)
(<$>) :: Functor f => (a->b) -> f a -> f b
(\x -> x * 2) <$> [1..2]
getSum $ fold $ Sum <$> [1..5]
- Applicative
(<*>) :: Applicative k => k (a -> b) -> k a -> k b
pure (\x -> x * 2) <*> [1..2]
getSum $ fold $ pure Sum <*> [1..5]
- Monad (bind function)
(>>=) :: Monad m => m a -> (a -> m b) -> m b
In real life, we see many computation cases that need to take value a
out of the computation context (or take value a
out of any context(structure) which denoted as m
)
The sample bellow, illustrate the case that we need to take a value a
out of Maybe
structure, and then calling (+)
function for a sum computation, and then put the result value into Maybe
structure.
maybePlus :: Maybe Int -> Maybe Int -> Maybe Int
maybePlus ma mb =
case ma of
Nothing -> Nothing
Just a ->
case mb of
Nothing -> Nothing
Just b -> Just (a + b)
-- helper function
andThen :: Maybe a -> (a -> Maybe b) -> Maybe b
andThen ma f =
case ma of
Nothing -> Nothing
Just a -> f a
-- using helper function to refactor
maybePlus' :: Maybe Int -> Maybe Int -> Maybe Int
maybePlus' ma mb = ma `andThen` \a -> mb `andThen` \b -> Just (a + b)
Relation between ($) (<>) <*>
($) :: (a -> b) -> a -> b
(<>) :: f -> f -> f
(<*>) :: f (a -> b) -> f a -> f b
We can see that (<*>)
indeed is the combination of ($)
and (<>)
Relation between <$> (=<<)
(<$>) :: (a -> b) -> f a -> f b
(=<<) :: (a-> m b) -> m a -> m b
We can see that flip bind function (=<<)
is the combination in order of fmap
and join :: Monad m => m (m a) -> m a
function. You can read more about the equivalent transformations here(english version coming soon, but i hope that you can understand the equivalent transformations)
Link to youtube video
Ref
- Monad tutorial in Vietnamese
- Credit to adit.io about pictures about functors, applicative and monad
- Of Algebirds, Monoids, Monads, and other Bestiary for Large-Scale Data Analytics