Skip to main content

4. Programming with Effects

16/02/23

Grahams question about life and programming:

Shall we be pure or impure?

pure = programs are mathematical functions impure = programs can have side effects

can we combine the two approaches (monads) Monads - Extracting a common pattern

Abstracting programming patterns

inc :: [Int] -> [Int]
inc [] = []
inc (n:ns) = n+1 : inc ns

sqr :: [Int] -> [Int]
sqr [] = []
sqr (n:ns) = n^s : sqr ns

Have similar functions, can use map to recursively execute same operation on all items in the list

map :: (a->b) -> [a] -> [b]
map f [] = []
map f (x:xs) = fx : map f xs

Can define inc and sqr in shorter way inc = map(+1) and sqr = map(n^2)

Generalising Further

class Functor f where
fmap :: (a->b) -> fa -> fb -- f is a member of the functor class if it follows the fmap rule successfully

List Functor

instance Functor [] where
-- fmap :: (a->b) -> [a] -> [b]
fmap = map

[] - parameterised type of list. It does not mean empty list

Maybe Functor

data Maybe a = Nothing | Just a

instance Functor Maybe where
-- fmap :: (a->b) -> Maybe a -> Maybe b
fmap g Nothing = Nothing
fmap g (Just x) = Just (g x)

The tree functor

data Tree a = Leaf a
| Node (Tree a) (Tree a)

instance Functor Tree where
-- fmap :: (a->b) -> Tree a -> Tree b
fmap g (Leaf x) = Leaf(g x)
fmap g (Node L r) = Node (fmap g l) (fmap g r)

g :: a->b
x :: a
L,r :: Tree a

Why use functors?

  1. Can use same name, for functions that are essentially the same
inc :: Functor f => f Int -> f Int
inc = fmap(+1)