Monad
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
instance Monad Box
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
, andMonad
and...- you get a
Functor
implementation for free!:liftM1
- you get an
Apply
implementation for free!:ap
- you get a
- Do a computation...
- if some condition is true:
whenM
- if some condition is false:
unlessM
- if some condition is true: