## Usage

Monad = Sequential Computation (`Bind`) + Lift a Value/Function into Box-like Type (`Applicative`)

## Definition

See its docs: Monad

``````class (Applicative m, Bind m) <= Monad m

data Box a = Box a

instance Functor Box where
map :: forall a b. (a -> b) -> Box a -> Box  b
map f (Box a) = Box (f a)

instance Apply Box where
apply :: forall a b. Box (a -> b) -> Box a -> Box  b
apply (Box f) (Box a) = Box (f a)

instance Bind Box where
bind :: forall a b. Box a -> (a -> Box b) -> Box b
bind (Box a) f = f a

instance Applicative Box where
pure :: forall a. a -> Box a
pure a =  Box a

``````

## Laws

### Unofficial

Taken from this slide in this YouTube video, here's an "unofficial" but clearer way to understand the laws for Monad by comparing them to a Function:

``````-- Recall: `identity a == (\x -> x) a`

-- Given a function whose type signature is...
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
(aToMB >=> bToMC) a = (aToMB a) >>= (\b -> bToMC b)

-- ... Monad could be defined by these laws:
-- 1a. Function's identity law
(function >>> identity) a == function a
aToMB    >=> pure        == aToMB

-- 1b. its inverse
(identity >>> f)        a == f a
pure     >=> f           == f

-- 2. Function Composition
f >>> (g >>> h) == (f >>> g) >>> h
f >=> (g >=> h) == (f >=> g) >=> h
``````

### Official

#### Identity

Definition (left) : `pure x >>= f = f x`

``````-- start
pure x  >>= f
-- replace call signature with body
(Box x) >>= f
-- de-infix `>>=` to `bind`
bind (Box x) f
-- replace call signature with body
f x
-- check LHS with RHS
f x == f x
-- Law met!
true
``````

Definition (right): `x >>= pure = x`

#### Applicative Superclass

Definition: `apply = ap` (where `ap` is a derived function)

## Derived Functions

• Define an instance of `Applicative`, `Bind`, and `Monad` and...
• you get a `Functor` implementation for free!: `liftM1`
• you get an `Apply` implementation for free!: `ap`
• Do a computation...
• if some condition is true: `whenM`
• if some condition is false: `unlessM`