Functor ᐧ Applicative ᐧ Monad

Michael Trotter

Jane.com

slack.utahjavascript.com

#fun-ctional

 

haskellbook.com

mostly adequate guide (to fp)

learn you a haskell

Abstraction

ints :: [Int]

sumInts :: [Int] -> Int
floats :: [Float]

sumFloats :: [Float] -> Float
bools :: [Bool]

sumBools :: [Bool] -> Bool
superInts :: [SuperInt]

sumSuperInts :: [SuperInt] -> SuperInt
xs :: [a]

sumXs :: [a] -> a
doStuff :: [a] -> a
doStuff = doAllTheThings

Typeclasses

doStuff :: [a] -> a

Typeclasses

doStuff = doAllTheThings
class Functor f where
  fmap :: (a -> b) -> f a -> f b

Typeclasses

instance Functor [] where
  fmap = map
class Monoid a where
  mempty  :: a
  mappend :: a -> a -> a
  mconcat :: [a] -> a

Monoid

class Monoid a where
  mempty  :: a
  mappend :: a -> a -> a
  mconcat :: [a] -> a

Perfect!

ints :: [Int]
ints = [1, 2, 3]

sumInts :: [Int] -> Int
sumInts xs = mconcat xs

sumInts ints

Nope, sorry.. :(

ints :: [Int]
ints = [1, 2, 3]

sumInts :: [Int] -> Int
sumInts xs = mconcat xs

multiplyInts :: [Int] -> Int
multiplyInts xs = mconcat xs

sumInts ints
multiplyInts ints

newtype

newtype Sum = Sum Int

instance Monoid Sum where
  mempty = Sum 0
  mappend (Sum x) (Sum y) = Sum (x + y)

newtype Product = Product Int

instance Monoid Product where
  mempty = Product 1
  mappend (Product x) (Product y) = Product (x * y)

there we go!

ints :: [Int]
ints = [1, 2, 3, 4]

sumInts :: [Int] -> Int
sumInts xs = getInt (mconcat (map Sum xs))

multiplyInts :: [Int] -> Int
multiplyInts xs = getProduct (mconcat (map Product xs))

sumInts ints      -- | 10
multiplyInts ints -- | 24

Functor

class Functor f where
  fmap :: (a -> b) -> f a -> f b
instance Functor [] where
  -- | :: (a -> b) -> [a] -> [b]
  fmap fn xs = map fn xs
instance Functor [] where
  fmap = map

Functor

ints :: [Int]
ints = [1, 2, 3, 4]

sumInts :: [Int] -> Int
sumInts xs = getInt (mconcat (fmap Sum xs))

multiplyInts :: [Int] -> Int
multiplyInts xs = getProduct (mconcat (fmap Product xs))

sumInts ints      -- | 10
multiplyInts ints -- | 24

Functor

fmap (+1) [1, 2, 3, 4] -- | [2, 3, 4, 5]

Functor

fmap (+1) (Just 1) -- | Just 2

fmap (+1) Nothing  -- | Nothing
data Maybe a = Nothing | Just a

Functor

fmap (+1) [1] -- | [2]

fmap (+1) []  -- | []

Functor

fmap (+1) (Just 1) -- | Just 2

fmap (+1) Nothing  -- | Nothing
instance Functor (Maybe a) where
  fmap fn (Just a) = Just (fn a)
  fmap _  Nothing  = Nothing

Monoid: reducible types

(Sum, Product, String, etc)

 

Functor: any data structure you map over -- fmap!

(List, Maybe, String, lots more!)

 

Another way to think about Functors:

 

A data structure you can run a computation inside

Functor-Applicative-Monad

By spicydonuts

Functor-Applicative-Monad

(the infamous)

  • 232