6 KiB
6 KiB
title | author | theme | classoption | ||||
---|---|---|---|---|---|---|---|
|
|
|
|
Agenda
- Recap of Functors
- Applicative
Functor12
class Functor f where
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
Functors Laws
- Must preserve identity
fmap id = id
- Must preserve composition of morphism
fmap (f . g) == fmap f . fmap g
Higher order kinds3
- For something to be a functor, it has to be a first order kind.
Applicative
class Functor f => Applicative (f :: TYPE -> TYPE) where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
fmap f x = pure f <*> x
Examples
pure (+1) <*> [1..3]
[2, 3, 4]
[(*2), (*3)] <*> [4, 5]
[8,10,12,15]
("Woo", (+1)) <*> (" Hoo!", 0)
("Woo Hoo!", 1)
(Sum 2, (+1)) <*> (Sum 0, 0)
(Sum {getSum = 2}, 1)
(Product 3, (+9)) <*> (Product 2, 8)
(Product {getProduct = 6}, 17)
(,) <$> [1, 2] <*> [3, 4]
[(1,3),(1,4),(2,3),(2,4)]
Use cases4
Person
<$> parseString "name" o
<*> parseInt "age" o
<*> parseTelephone "telephone" o
Can also be written as
liftA3 Person
(parseString "name" o)
(parseInt "age" o)
(parseTelephone "telephone" o)
Use cases5
parsePerson :: Parser Person
parsePerson = do
string "Name: "
name <- takeWhile (/= 'n')
endOfLine
string "Age: "
age <- decimal
endOfLine
pure $ Person name age
Use cases6
helper :: () -> Text -> () -> () -> Int -> () -> Person
helper () name () () age () = Person name age
parsePerson :: Parser Person
parsePerson = helper
<$> string "Name: "
<*> takeWhile (/= 'n')
<*> endOfLine
<*> string "Age: "
<*> decimal
<*> endOfLine
Lifting
- Seeing Functor as unary lifting and Applicative as n-ary lifting
liftA0 :: Applicative f => (a) -> (f a)
liftA1 :: Functor f => (a -> b) -> (f a -> f b)
liftA2 :: Applicative f => (a -> b -> c) -> (f a -> f b -> f c)
liftA3 :: Applicative f => (a -> b -> c -> d) -> (f a -> f b -> f c -> f d)
liftA4 :: Applicative f => ..
Where liftA0 = pure
and liftA1 = fmap
.
Monoidal functors
- Remember Monoid?
class Monoid m where
mempty :: m
mappend :: m -> m -> m
($) :: (a -> b) -> a -> b
(<$>) :: (a -> b) -> f a -> f b
(<*>) :: f (a -> b) -> f a -> f b
mappend :: f f f
($) :: (a -> b) -> a -> b
<*> :: f (a -> b) -> f a -> f b
instance Monoid a => Applicative ((,) a) where
pure x = (mempty, x)
(u, f) <*> (v, x) = (u `mappend` v, f x)
Where are monoids again
fmap (+1) ("blah", 0)
("blah",1)
("Woo", (+1)) <*> (" Hoo!", 0)
("Woo Hoo!", 1)
(,) <$> [1, 2] <*> [3, 4]
[(1,3),(1,4),(2,3),(2,4)]
liftA2 (,) [1, 2] [3, 4]
[(1,3),(1,4),(2,3),(2,4)]
Function apply
- Applying a function to an
effectful
argument
(<$>) :: Functor m => (a -> b) -> m a -> m b
(<*>) :: Applicative m => m (a -> b) -> m a -> m b
(=<<) :: Monad m => (a -> m b) -> m a -> m b
Contrasts with monad
- No data dependency between
f a
andf b
- Result of
f a
can't possibly influence the behaviour off b
- That needs something like
a -> f b
Applicative laws
-- Identity
pure id <*> v = v
-- Composition
pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
-- Homomorphism
pure f <*> pure x = pure (f x)
-- Interchange
u <*> pure y = pure ($ y) <*> u
Operators7
pure
wraps up a pure value into some kind of ApplicativeliftA2
applies a pure function to the values inside twoApplicative
wrapped values<$>
operator version offmap
<*>
apply a wrapped function to a wrapped value*>
,<*
Applicative vs monads
-
Applicative
- Effects
- Batching and aggregation
- Concurrency/Independent
- Parsing context free grammar
- Exploring all branches of computation (see
Alternative
)
-
Monads
- Effects
- Composition
- Sequence/Dependent
- Parsing context sensitive grammar
- Branching on previous results
Weaker but better
- Weaker than monads but thus also more common
- Lends itself to optimisation (See Facebook's Haxl project)
- Always opt for the least powerful mechanism to get things done
- No dependency issues or branching? just use applicative
Resources
- Applicative Programming with Effects
- optparse-applicative
- Control Applicative
- Applicative functors for fun & parsing
Questions
- Reach out on
- Email: sanchayan@sanchayanmaity.net
- Mastodon: sanchayanmaity.com
- Telegram: t.me/SanchayanMaity
- Blog: sanchayanmaity.net