Skip to content

Latest commit

 

History

History
63 lines (44 loc) · 1.79 KB

07_ApplicativeAndMonad.md

File metadata and controls

63 lines (44 loc) · 1.79 KB

Applicative and Monad

[ToC]

In this chapter, we are going to look at two very important type class, Applicative Functor and Monad.

Functor

TODO:...

Applicative

Let's start with how the Applicative class is defined. From the definition, we can see that Applicatives are Functors with two more operations, which is pure and apply. pure wraps some value to make an applicative functor. apply is a bit more complicated.

Let's just look at its type, does that ring a bell? Yeah, it looks like map except we have functions wrapped inside an applicative functor. What apply does is extract the function(s) from the functor and map them to the f a .

class Functor f => Applicative f where
  pure  :: forall a. a -> f a
  apply :: forall a b. f (a -> b) -> f a -> f b

infixl 4 apply as <*>

Here are some examples of intances of Applicatve

instance Applicative Maybe where
  pure = Just
  Nothing   <*> mb = Nothing
  (Just f) <*> mb = map f mb

Let's have a closer look at instance Applicative [] , we can see that every f in the list will get applied to all the elements in the list. So with (+) <$> [1,2] <*> [3,4,5], we will have a non-deterministic computation on (+).

Monad

class Applicative m => Monad m where
  bind :: forall a b. m a -> (a -> m b) -> m b
  return :: forall a. a -> m a

lifting

liftA1 :: forall a b f. Applicative f => (a -> b) -> f a -> f b
liftA1 f a = pure f <*> a

liftA2 :: forall a b c f. Applicative f => (a -> b -> c) -> f a -> f b -> f c
liftA2 f a b = pure f <*> a <*> b

liftM1 :: forall a b m. Monad m => (a -> b) -> m a -> m b
liftM1 f ma = do
  a <- ma
  return (f a)

liftM2 :: forall a b c m. Monad m => (a -> b -> c) -> m a -> m b -> m c
liftM2 f ma mb = do
  a <- ma
  b <- mb
  return (f a b)