## ~williamvds/university

a81d20700a0ecf9560eb6c57ff38c2b5829a6645 — williamvds 6 years ago
```afp notes
```
```1 files changed, 192 insertions(+), 0 deletions(-)

A afp/lectures.md
```
`A afp/lectures.md => afp/lectures.md +192 -0`
```@@ 0,0 1,192 @@
+# Functors
+
+class Functor f where
+  fmap :: (a -> b) -> f a -> f b
+```
+
+## Examples
+
+### Maybe
+
+instance Functor Maybe where
+  -- fmap :: (a -> b) -> Maybe a -> Maybe b
+  fmap _ Nothing  = Nothing
+  fmap g (Just x) = Just (g x)
+```
+
+### Lists
+
+instance Functor [] where
+  -- fmap :: (a -> b) -> [a] -> [b]
+  fmap = map
+```
+- Applies a function to all elements
+
+## Laws
+fmap id      = id
+fmap (g . h) = fmap g . fmap h
+```
+- 1st: `fmap` preserves the identity function
+- 2nd: `fmap` preserves function composition
+
+
+# Applicative Functors
+- Allow mapping a function with any number of arguments, rather than just ones
+with a single argument
+
+class Functor f => Applicative f where
+  pure :: a -> f a
+  (<*>) :: f (a -> b) -> f a -> f b
+```
+
+## Examples
+
+### Maybe
+
+instance Applicative Maybe where
+  -- pure :: a -> Maybe a
+  pure = Just
+  -- (<*>) :: Maybe (a -> b) -> Maybe a -> Maybe b
+  Nothing  <*> _   = Nothing
+  (Just g) <*> mx  = fmap g mx
+
+> pure (+1) <*> Just 1
+Just 2
+> pure (+) <*> Just 1 <*> Just 2
+Just 3
+> pure (+) <*> Nothing <*> Just 2
+Nothing
+```
+- Supports _exceptional_ programming - applying pure functions to arguments
+which may fail
+
+### Lists
+instance Applicative [] where
+  -- pure :: a -> [a]
+  pure x = [x]
+  -- (<*>) :: [a -> b] -> [a] -> [b]
+  gs <*> xs = [g x | g <- gs, x <- xs]
+
+> pure (+1) <*> [1,2,3]
+[2,3,4]
+> pure (+) <*> [1] <*> [2]
+[3]
+> pure (*) <*> [1,2] <*> [3,4]
+[3,4,6,8]
+```
+-- Applicative style for lists takes a list of functions and a list of
+arguments, applying each in turn and returning a list of all results
+
+## Laws
+
+pure id <*> x 	= x
+pure (g x) 		  = pure g <*> pure x
+x <*> pure y 	  = pure (\g -> g y) <*> x
+x <*> (y <*> z) = (pure (.) <*> x <*> y) <*> z
+```
+- 1st: `pure` preserves the identity function - applying `pure` to it gives
+an applicative version of it
+- 2nd: `pure` preserves function application - it distributes over normal
+function application to give applicative application
+- 3rd: When an effectful function is applied to a pure argument, the order
+in which the components are evaluated doesn't matter
+- 4th: (Compensating for types) `<*>` is associative
+
+Comes from a branch of mathematics called _branch theory_.
+class Applicative m => Monad m where
+  (>>=) :: m a -> (a -> m b) -> mb
+  return :: a -> ma
+  return = pure
+```
+
+## Examples
+
+### Maybe
+  -- (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
+  Nothing  >>= f = Nothing
+  (Just x) >>= f = f x
+```
+
+### Lists
+  -- (>>=) :: [a] -> (a -> [b]) -> [b]
+  [] >>= f = []
+  xs >>= f = concat \$ map f xs -- (map f xs) :: [[b]], use concat to flatten
+           = [y | x <- xs, y <- f x]
+
+> pairs [1, 2] [3, 4]
+[(1, 3), (1, 4), (2, 3), (2, 4)]
+
+-- The cartesian product of two lists
+pairs :: [a] -> [b] -> [(a, b)]
+pairs xs ys = do x <- xs
+                 y <- ys
+                 return (x,y)
+            = xs >>= \x ->
+              ys >>= \y ->
+              return (x, y)
+-- similar to list comprehension [(x, y) | x <- xs, y <- ys]
+```
+
+List comprehensions are useful only to lists, whereas the do notation is general
+
+### State
+type State = ...
+type ST = State -> State -- state transformer: take current state and return new
+type ST a = State -> (a, State) -- typed state transformer, of what is returned
+
+Char -> ST Int
+= Char -> State -> (Int, State)
+-- ST abstracts away the state from the function type
+
+type ST a = State -> (a, State)
+
+-- Needs to be data in order to make a class definition
+newtype ST a = S(State -> (a, State))
+
+-- Get rid of 'dummy' constructor
+app (S st) s = st s
+
+-- TODO create functor and applicative
+
+  -- return :: a -> ST a
+  return x = S (\s -> (x, s))
+  -- s is the only State available, x is of type a
+
+  -- (>>=) :: ST a -> (a -> ST b) -> ST b
+  st >> f = S (\s -> let (x, s') = app st s
+                     in app (f x) s')
+  -- state transformer applied to s, returning value x and new state s'
+  -- apply f to x and s', returning two new values (eg names y and s'')
+```
+## Laws
+return x >>= f = f x
+mx >>= return  = mx
+```
+- Link between `return` and `>>=`
+- 1st: `return`ing a value and feeding it into a monadic function = applying
+the function to the value
+- 2nd: Feeding the result of a monadic computation into `return` is the same
+as performing the computation
+- `return` is the identity for `>>=`
+