Skip to content

Latest commit

 

History

History
302 lines (209 loc) · 4.55 KB

Day5.md

File metadata and controls

302 lines (209 loc) · 4.55 KB

Day 5

Pitch

  • Top 10 IRC channel: #haskell
  • Reddit: > 10k subscribers
  • Stack Overflow: > 10k questions
  • Learn from smarter people.

helpful

MONADS

dragon

Why?

PURE functional. NO side effects. Everything returns, should be deterministic.

Life isn't deterministic. This is why people think it's not useful.

HOW do we deal with LIFE?

  • Side effects in IO
  • Pure everywhere else

brilliant

Details

Drawn from, return (opposites)

main :: IO ()
main = do
  putStrLn "quit the program? y/n"
  ans <- getLine
  if ans /= "y" then do
    putStrLn "not quitting"
    main
  else return ()

  -- or
  when (ans /= "y") $ do
    putStrLn "not quitting"
    main

Show Project SETUP

We'll have:

  • Parsing
  • DB
  • WS Server
  • Solver

Values

Next slides are from this excellent tutorial.

Value

Applying Functions

Applying

Value in context

Context

Applying

Applying functions now depends on context:

Maybe

data Maybe a = Just a | Nothing

How to Apply?

Ouch

Fmap!

fmap (+3) (Just 2)

Fmap

Functors!

Functor is a typeclass:

Functor

Internals

Functor is just a data type that defines fmap for itself:

fmap

So we can:

instance Functor Maybe where
    fmap func (Just val) = Just (func val)
    fmap func Nothing = Nothing

fmap (+3) (Just 2)

Visually

Behind the scenes of fmap (+3) (Just 2) we get:

fmapping

What About Nothing?

Try to apply (+3) to Nothing and you get:

fnothing

ghci>fmap (+3) Nothing
Nothing

Bottoms

Nil is often used as bottom as well as status. In Haskell we still have bottom: undefined.

Because bottom subsumes non-termination, the function isUndefined would have to solve the halting problem and thus cannot exist.

post = Post.find_by_id(1)
if post
  return post.title
else
  return nil
end
fmap (getPostTitle) (findPost 1)
--- or with infix
getPostTitle <$> (findPost 1)

Function to List?

ftolist

Because:

instance Functor [] where
    fmap = map

What About Functions?

Normal:

regular

What About?:

applied

fmap (+3) (*2)

How?

instance Functor ((->) r) where
    fmap f g = f . g

As a functor, it's function composition! As a monad:

instance Applicative ((->) r) where
   -- pure :: a -> r -> a
   pure = const

   -- (<*>) :: (r -> a -> b) -> (r -> a) -> r -> b
   (<*>) g f r = g r (f r)

instance Monad ((->) r) where
    -- return :: a -> r -> a
    return = const
    -- (>>=) :: (r -> a) -> (a -> r -> b) -> r -> b
    (>>=) x y z = y (x z) z

Applicatives

Both are wrapped in contexts!

Just 2
Just (+3)

j2 j2

To interact:

j3

ghci>Just (+2) <*> Just 5

More Complicated now

From base:

instance Functor [] where
    fmap = map

instance Applicative [] where
    pure x    = [x]
    fs <*> xs = [f x | f <- fs, x <- xs]
    xs *> ys  = [y | _ <- xs, y <- ys]

instance Monad []  where
    xs >>= f             = [y | x <- xs, y <- f x]
    (>>) = (*>)
    return x            = [x]
    fail _              = []

What is this?

-- So... what is this?
[(*2),(+3)] <*> [1, 2, 3]

. . .

answer

Applicatives CAN, Functors CAN'T

Apply function that takes 2 args to 2 wrapped values!

ghci>(+) <$> (Just 5)
Just (+5)
ghci>Just (+5) <$> Just 4
ERRRRR

. . .

-- Applicative
ghci>(+) <$> Just 5 <*> Just 4
Just 9
ghci>liftA2 (*) (Just 5) (Just 3)
Just 15