Skip to main content

6. Monads I

23/02/23

Refresh - Functor

-- f is a type like lists, tree
class Functor f where
fmap :: (a->b) -> f a -> f b -- f is a data structure

If already have a functor, can be an Applicative (using =>). Have to follow a set of conditions using where.

Applicative functors - captures a basic form or a basic pattern with affect.

Applicative style is pure functions applied to effect for arguments

Example: simple evaluator

data Expr = Val Int | Div Expr Expr

eval :: Expr -> Int
eval (Val n) = n
eval (Div x y) = eval x `div` eval y -- could crash if x/y is 0

Safediv

This is a safe version of div

safediv :: Int -> Int -> Maybe Int
safediv _ 0 = Nothing
safediv n m = Just (n `div` m)

Now rewrite Expr so it can use safediv

safediv :: Int -> Maybe Int
eval (Val n) = Just n
eval (Div x y) = case eval x of
Nothing -> Nothing
Just n -> case eval y of
Nothing -> Nothing
Just m -> safediv n m

This function will never crash, however it is a bit complicated. But can simplify this further

eval :: Expr -> Maybe Int
eval (Val n) = pure n
eval (Div x y) = pure safediv (*) eval x (*) eval y -- Best, however this cause a type error

Safediv is not a pure function as it returns a maybe type

Template box

This is a case analyses on something ([BOX])

case [BOX] of
Nothing -> Nothing
Just x -> [BOX] x

Can turn this template into ->

mx >>= f = case mx of 
Nothing -> Nothing
Just x -> f x
(>>=) :: Maybe a -> (a -> )

eval :: Expr -> Maybe Int
eval (Val n) = Just n
eval (Div x y) = eval x >>= (\n ->
eval y >>= (\m ->
safediv n m)

>>= is an into operator

do notation

As this occurs frequently, can use the do notation. Its like a syntax sugar.

eval :: Expr -> Maybe Int
eval (Val n) = Just n
eval (Div x y) = do n <- eval x
m <- eval y
safediv n m