SlideShare a Scribd company logo
1 of 96
Download to read offline
Applicative Functors
Łukasz Marchewka @scalac
Functor
Functor
class Functor f where
fmap :: (a -> b) -> f a -> f b
Functor
class Functor f where
fmap :: (a -> b) -> f a -> f b
Functor
class Functor f where
fmap :: (a -> b) -> f a -> f b
Functor
class Functor f where
fmap :: (a -> b) -> f a -> f b
Functor
class Functor f where
fmap :: (a -> b) -> f a -> f b
Functor
class Functor f where
fmap :: (a -> b) -> f a -> f b
Monad
Monad
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Monad
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Monad
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Monad
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Monad
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Monad
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Monad
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Monad
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Monad
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Applicative
Applicative
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Applicative
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Applicative
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Applicative
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Applicative
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Applicative
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Applicative
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Applicative
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Applicative
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Applicative
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Applicative
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Applicative
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Applicative
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Applicative
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Details
Applicative
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
(*>) :: f a -> f b -> f b
(<*) :: f a -> f b -> f a
Applicative
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
(*>) :: f a -> f b -> f b
(<*) :: f a -> f b -> f a
Applicative
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
(*>) :: f a -> f b -> f b
(<*) :: f a -> f b -> f a
Applicative
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
(*>) :: f a -> f b -> f b
(<*) :: f a -> f b -> f a
Applicative
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
(*>) :: f a -> f b -> f b
(<*) :: f a -> f b -> f a
Applicative
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
(*>) :: f a -> f b -> f b
(<*) :: f a -> f b -> f a
Applicative
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
(*>) :: f a -> f b -> f b
(<*) :: f a -> f b -> f a
Simple example
Types
newtype Nickname = Nickname { getNickname :: String }
newtype Age = Age { getAge :: Int }
data User = User Nickname Age
> :t User
User :: Nickname -> Age -> User
As a function
readNickname :: Nickname
readAge :: Age
readUser :: User
readUser = User readNickname readAge
With a context
readNickname' :: IO Nickname
readAge' :: IO Age
Using Monad
readNickname' :: IO Nickname
readAge' :: IO Age
readUserM :: IO User
readUserM = do
nickname <- readNickname'
age <- readAge'
return $ User nickname age
Using Applicative
readNickname' :: IO Nickname
readAge' :: IO Age
readUserA :: IO User
readUserA = pure User <*> readNickname' <*> readAge'
readNickname' :: IO Nickname
readAge' :: IO Age
readUserA :: IO User
readUserA = User <$> readNickname' <*> readAge'
Using Applicative
readNickname' :: IO Nickname
readAge' :: IO Age
readUserA :: IO User
readUserA = User <$> readNickname' <*> readAge'
Using Applicative
An infix synonym for 'fmap'
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<$>) = fmap
Function vs Applicative
readNickname :: Nickname
readAge :: Age
User readNickname readAge
readNickname' :: IO Nickname
readAge' :: IO Age
User <$> readNickname' <*> readAge'
Applicative vs Monad
readNickname' :: IO Nickname
readNickname' = do
putStrLn "Your nickname:"
str <- getLine
if length str > 0
then return $ Nickname str
else error "Nickname can't be empty"
readAge' :: IO Age
readAge' = do
putStrLn "Your age:"
fmap (Age . read) getLine
Applicative vs Monad
readUserA :: IO User
readUserA = User <$> readNickname' <*> readAge'
readUserM :: IO User
readUserM = do
nickname <- readNickname'
age <- readAge'
return $ User nickname age
Applicative
Functor < Applicative < Monad
Why ?
Relation
Functor
Relation
Functor
Applicative
Relation
Functor
Applicative
Monad
When we need
● Context-free validation/parsing/transformation/optimization/...
● Parallel computation
● Traverlable
● Easier to compose than Monads
● When we can’t / don’t want to create Monad because of extra laws
Relation
Functor
Applicative
Monad
Examples
Example: Validation
● ???
● ???
● ...
Example: Validation
● Option
● Try
● Either
● ...
Example: Validation
data Either a b = Left a | Right b
Example: Validation
validateNickname :: String -> Either [String] Nickname
validateNickname str
| size < 1 = Left [ "Nickname must have at least 1 character" ]
| size > 10 = Left [ "Nickname must have at most 10 characters" ]
| otherwise = Right $ Nickname str
where size = Data.List.length str
validateAge :: Int -> Either [String] Age
validateAge val
| val < 0 = Left [ "Minimal age is 0" ]
| val > 150 = Left [ "Maximal age is 150" ]
| otherwise = Right $ Age val
Example: Validation
validateUser :: String -> Int -> Either [String] User
validateUser nickname age =
User
<$> (validateNickname nickname)
<*> (validateAge age)
Example: Validation
> validateUser "" 200
Example: Validation
> validateUser "" 200
Left ["Nickname must have at least 1 character"]
Example: Validation
> validateUser "" 200
Left ["Nickname must have at least 1 character"]
> validateUser "john" 200
Example: Validation
> validateUser "" 200
Left ["Nickname must have at least 1 character"]
> validateUser "john" 200
Left ["Maximal age is 150"]
Example: Validation
> validateUser "" 200
Left ["Nickname must have at least 1 character"]
> validateUser "john" 200
Left ["Maximal age is 150"]
> validateUser "john" 20
Right (User (Nickname {getNickname = "john"}) (Age {getAge = 20}))
Example: Validation
data Either a b = Left a | Right b
Example: Validation
data Either a b = Left a | Right b -- fail fast
Example: Validation
import Data.Validation
data Validation err a = Failure err | Success a
data Either a b = Left a | Right b
Example: Validation
● A data-type like Either but with an accumulating Applicative
● The Validation data type is isomorphic to Either
● An applicative functor that is not a monad
Example: Validation
● A data-type like Either but with an accumulating Applicative
● The Validation data type is isomorphic to Either
● An applicative functor that is not a monad
Example: Validation
validateNicknameA :: String -> Validation (NonEmpty String) Nickname
validateNicknameA str
| size < 1 = Failure $ "Nickname must have at least 1 character" :| []
| size > 10 = Failure $ "Nickname must have at most 10 characters" :| []
| otherwise = Success $ Nickname str
where size = Data.List.length str
validateAgeA :: Int -> Validation (NonEmpty String) Age
validateAgeA val
| val < 0 = Failure $ "Minimal age is 0" :| []
| val > 150 = Failure $ "Maximal age is 150" :| []
| otherwise = Success $ Age val
Example: Validation
validateUserA :: String -> Int -> Validation (NonEmpty String) User
validateUserA nickname age =
User
<$> (validateNicknameA nickname)
<*> (validateAgeA age)
Example: Validation
> validateUserA "" 200
Example: Validation
> validateUserA "" 200
Failure ("Nickname must have at least 1 character" :| ["Maximal age is 150"])
Example: Validation
> validateUserA "" 200
Failure ("Nickname must have at least 1 character" :| ["Maximal age is 150"])
> validateUserA "john" 20
Success (User (Nickname {getNickname = "john"}) (Age {getAge = 20}))
Either vs Validation
instance Applicative (Either e) where
pure = Right
Left e <*> _ = Left e
Right f <*> r = fmap f r
instance Applicative (Validation err) where
pure = Success
Failure e1 <*> b = Failure $ case b of
Failure e2 -> e1 <> e2
Success _ -> e1
Success _ <*> Failure e2 =
Failure e2
Success f <*> Success a =
Success (f a)
Example: haxl
● batch multiple requests to the same data source
● request data from multiple data sources concurrently
● cache previous requests
● memoize computations
numCommonFriends x y =
length
<$> (intersect <$> friendsOf x <*> friendsOf y)
Example: Composition
readValidNickname :: IO (Maybe Nickname)
readValidNickname = do
putStrLn "Your name:"
str <- getLine
if length str > 0
then return $ Just $ Nickname str
else return Nothing
readValidAge :: IO (Maybe Age)
readValidAge = do
putStrLn "Your age:"
str <- getLine
return $ fmap Age $ readMaybe str
Example: Composition
readValidUserM :: IO (Maybe User)
readValidUserM = runMaybeT $ do
nickname <- MaybeT readValidNickname
age <- MaybeT readValidAge
return $ User nickname age
Example: Composition
readValidUserA :: IO (Maybe User)
readValidUserA = unComp1
(User <$> (Comp1 readValidNickname) <*> (Comp1 readValidAge))
Example: Composition
readValidUserA :: IO (Maybe User)
readValidUserA = unComp1
(User <$> (Comp1 readValidNickname) <*> (Comp1 readValidAge))
newtype (:.:) (f :: k2 -> Type) (g :: k1 -> k2) (p :: k1) =
Comp1 { unComp1 :: f (g p) }
Example: Composition
newtype (:.:) (f :: k2 -> Type) (g :: k1 -> k2) (p :: k1) =
Comp1 { unComp1 :: f (g p) }
instance (Applicative f, Applicative g) => Applicative (f :.: g) where
pure x = Comp1 (pure (pure x))
Comp1 f <*> Comp1 x = Comp1 (liftA2 (<*>) f x)
liftA2 f (Comp1 x) (Comp1 y) = Comp1 (liftA2 (liftA2 f) x y)
Example: Free
data Field a =
StringField Name Doc
| IntField Name Doc
| BoolField Name Doc
| ObjectField Name Doc (Ap Field a)
Example: Free
type Dsl a = Ap Field a
string :: Name -> Doc -> Dsl String
string n d = liftAp $ StringField n d
int :: Name -> Doc -> Dsl Int
int n d = liftAp $ IntField n d
bool :: Name -> Doc -> Dsl Bool
bool n d = liftAp $ BoolField n d
object :: Name -> Doc -> Dsl a -> Dsl a
object n d a = liftAp $ ObjectField n d a
Example: Free
data User = User String Int Bool
data Comment = Comment String User
user :: Dsl User
user = User
<$> string "name" "user's name"
<*> int "age" "user's age"
<*> bool "active" "is active"
comment :: Dsl Comment
comment = Comment
<$> string "title" "short desc"
<*> object "creator" "who created the comment" user
Example: Free
Comment
User String
String Int Bool
Example: Free
genDoc :: Int -> Field a -> [String]
genDoc indent (StringField n d) = [printf "%*s- %s : string - %s" indent "" n d]
genDoc indent (IntField n d) = [printf "%*s- %s : int - %s" indent "" n d]
genDoc indent (BoolField n d) = [printf "%*s- %s : bool - %s" indent "" n d]
genDoc indent (ObjectField n d m) = asString : nested
where
asString = printf "%*s- %s : obj - %s" indent "" n d
nested = runAp_ (genDoc $ indent + 2) m
Example: Free
printDoc :: IO ()
printDoc = mapM_ putStrLn lines
where lines = runAp_ (genDoc 0) comment
- title : string - short desc
- creator : obj - creator of the comment
- name : string - user's name
- age : int - user's age
- active : bool - is active
Example: Free
● JSON, XML, ... <-> Model
● Transformation (context-free)
● … (context-free)
Thank You!
lukasz.marchewka@gmail.com
https://github.com/LukaszMarchewka/haskell-applicative-demo

More Related Content

Similar to Applicative functors by Łukasz Marchewka

アプリカティブファンクターとHaskell 2014版
アプリカティブファンクターとHaskell 2014版アプリカティブファンクターとHaskell 2014版
アプリカティブファンクターとHaskell 2014版infinite_loop
 
Functions in python
Functions in pythonFunctions in python
Functions in pythonIlian Iliev
 
Swift 3.0 で変わったところ - 厳選 13 項目 #love_swift #cswift
Swift 3.0 で変わったところ - 厳選 13 項目 #love_swift #cswiftSwift 3.0 で変わったところ - 厳選 13 項目 #love_swift #cswift
Swift 3.0 で変わったところ - 厳選 13 項目 #love_swift #cswiftTomohiro Kumagai
 
Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)stasimus
 
하스켈 프로그래밍 입문 3
하스켈 프로그래밍 입문 3하스켈 프로그래밍 입문 3
하스켈 프로그래밍 입문 3Kwang Yul Seo
 

Similar to Applicative functors by Łukasz Marchewka (8)

アプリカティブファンクターとHaskell 2014版
アプリカティブファンクターとHaskell 2014版アプリカティブファンクターとHaskell 2014版
アプリカティブファンクターとHaskell 2014版
 
09. haskell Context
09. haskell Context09. haskell Context
09. haskell Context
 
10. haskell Modules
10. haskell Modules10. haskell Modules
10. haskell Modules
 
Functions in python
Functions in pythonFunctions in python
Functions in python
 
Swift 3.0 で変わったところ - 厳選 13 項目 #love_swift #cswift
Swift 3.0 で変わったところ - 厳選 13 項目 #love_swift #cswiftSwift 3.0 で変わったところ - 厳選 13 項目 #love_swift #cswift
Swift 3.0 で変わったところ - 厳選 13 項目 #love_swift #cswift
 
Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)
 
MP in Clojure
MP in ClojureMP in Clojure
MP in Clojure
 
하스켈 프로그래밍 입문 3
하스켈 프로그래밍 입문 3하스켈 프로그래밍 입문 3
하스켈 프로그래밍 입문 3
 

More from Scalac

AWS Api Gateway by Łukasz Marchewka Scalacc
AWS Api Gateway by Łukasz Marchewka ScalaccAWS Api Gateway by Łukasz Marchewka Scalacc
AWS Api Gateway by Łukasz Marchewka ScalaccScalac
 
Do ECTL not ETL: the art and science of data cleansing in data pipelines by P...
Do ECTL not ETL: the art and science of data cleansing in data pipelines by P...Do ECTL not ETL: the art and science of data cleansing in data pipelines by P...
Do ECTL not ETL: the art and science of data cleansing in data pipelines by P...Scalac
 
React Hooks by Oleksandr Oleksiv Scalac
React Hooks by Oleksandr Oleksiv ScalacReact Hooks by Oleksandr Oleksiv Scalac
React Hooks by Oleksandr Oleksiv ScalacScalac
 
Introduction to Scala by Piotr Wiśniowski Scalac
Introduction to Scala by Piotr Wiśniowski ScalacIntroduction to Scala by Piotr Wiśniowski Scalac
Introduction to Scala by Piotr Wiśniowski ScalacScalac
 
ZIO actors by Mateusz Sokół Scalac
ZIO actors by Mateusz Sokół ScalacZIO actors by Mateusz Sokół Scalac
ZIO actors by Mateusz Sokół ScalacScalac
 
Why functional programming and category theory strongly matters - Piotr Parad...
Why functional programming and category theory strongly matters - Piotr Parad...Why functional programming and category theory strongly matters - Piotr Parad...
Why functional programming and category theory strongly matters - Piotr Parad...Scalac
 
Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Scalac
 
How to write automated tests and don’t lose your mind by Dorian Sarnowski Scalac
How to write automated tests and don’t lose your mind by Dorian Sarnowski ScalacHow to write automated tests and don’t lose your mind by Dorian Sarnowski Scalac
How to write automated tests and don’t lose your mind by Dorian Sarnowski ScalacScalac
 
Do you have that Spark in your ECTL? by Piotr Sych Scalac
Do you have that Spark in your ECTL? by Piotr Sych ScalacDo you have that Spark in your ECTL? by Piotr Sych Scalac
Do you have that Spark in your ECTL? by Piotr Sych ScalacScalac
 
Can we automate the process of backlog prioritizing? by Adam Gadomski Scalac
Can we automate the process of backlog prioritizing? by Adam Gadomski ScalacCan we automate the process of backlog prioritizing? by Adam Gadomski Scalac
Can we automate the process of backlog prioritizing? by Adam Gadomski ScalacScalac
 
How to create the right sales funnel for your business? by Maciej Greń
How to create the right sales funnel for your business? by Maciej GreńHow to create the right sales funnel for your business? by Maciej Greń
How to create the right sales funnel for your business? by Maciej GreńScalac
 
ActorRef[Typed] by Andrzej Kopeć
ActorRef[Typed] by Andrzej KopećActorRef[Typed] by Andrzej Kopeć
ActorRef[Typed] by Andrzej KopećScalac
 
Scala 3camp 2011
Scala   3camp 2011Scala   3camp 2011
Scala 3camp 2011Scalac
 
Liftweb
LiftwebLiftweb
LiftwebScalac
 
Scala == Effective Java
Scala == Effective JavaScala == Effective Java
Scala == Effective JavaScalac
 
Scala and Lift presentation
Scala and Lift presentationScala and Lift presentation
Scala and Lift presentationScalac
 

More from Scalac (16)

AWS Api Gateway by Łukasz Marchewka Scalacc
AWS Api Gateway by Łukasz Marchewka ScalaccAWS Api Gateway by Łukasz Marchewka Scalacc
AWS Api Gateway by Łukasz Marchewka Scalacc
 
Do ECTL not ETL: the art and science of data cleansing in data pipelines by P...
Do ECTL not ETL: the art and science of data cleansing in data pipelines by P...Do ECTL not ETL: the art and science of data cleansing in data pipelines by P...
Do ECTL not ETL: the art and science of data cleansing in data pipelines by P...
 
React Hooks by Oleksandr Oleksiv Scalac
React Hooks by Oleksandr Oleksiv ScalacReact Hooks by Oleksandr Oleksiv Scalac
React Hooks by Oleksandr Oleksiv Scalac
 
Introduction to Scala by Piotr Wiśniowski Scalac
Introduction to Scala by Piotr Wiśniowski ScalacIntroduction to Scala by Piotr Wiśniowski Scalac
Introduction to Scala by Piotr Wiśniowski Scalac
 
ZIO actors by Mateusz Sokół Scalac
ZIO actors by Mateusz Sokół ScalacZIO actors by Mateusz Sokół Scalac
ZIO actors by Mateusz Sokół Scalac
 
Why functional programming and category theory strongly matters - Piotr Parad...
Why functional programming and category theory strongly matters - Piotr Parad...Why functional programming and category theory strongly matters - Piotr Parad...
Why functional programming and category theory strongly matters - Piotr Parad...
 
Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...
 
How to write automated tests and don’t lose your mind by Dorian Sarnowski Scalac
How to write automated tests and don’t lose your mind by Dorian Sarnowski ScalacHow to write automated tests and don’t lose your mind by Dorian Sarnowski Scalac
How to write automated tests and don’t lose your mind by Dorian Sarnowski Scalac
 
Do you have that Spark in your ECTL? by Piotr Sych Scalac
Do you have that Spark in your ECTL? by Piotr Sych ScalacDo you have that Spark in your ECTL? by Piotr Sych Scalac
Do you have that Spark in your ECTL? by Piotr Sych Scalac
 
Can we automate the process of backlog prioritizing? by Adam Gadomski Scalac
Can we automate the process of backlog prioritizing? by Adam Gadomski ScalacCan we automate the process of backlog prioritizing? by Adam Gadomski Scalac
Can we automate the process of backlog prioritizing? by Adam Gadomski Scalac
 
How to create the right sales funnel for your business? by Maciej Greń
How to create the right sales funnel for your business? by Maciej GreńHow to create the right sales funnel for your business? by Maciej Greń
How to create the right sales funnel for your business? by Maciej Greń
 
ActorRef[Typed] by Andrzej Kopeć
ActorRef[Typed] by Andrzej KopećActorRef[Typed] by Andrzej Kopeć
ActorRef[Typed] by Andrzej Kopeć
 
Scala 3camp 2011
Scala   3camp 2011Scala   3camp 2011
Scala 3camp 2011
 
Liftweb
LiftwebLiftweb
Liftweb
 
Scala == Effective Java
Scala == Effective JavaScala == Effective Java
Scala == Effective Java
 
Scala and Lift presentation
Scala and Lift presentationScala and Lift presentation
Scala and Lift presentation
 

Recently uploaded

chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
software engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxsoftware engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxnada99848
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 

Recently uploaded (20)

chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
software engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxsoftware engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptx
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 

Applicative functors by Łukasz Marchewka

  • 3. Functor class Functor f where fmap :: (a -> b) -> f a -> f b
  • 4. Functor class Functor f where fmap :: (a -> b) -> f a -> f b
  • 5. Functor class Functor f where fmap :: (a -> b) -> f a -> f b
  • 6. Functor class Functor f where fmap :: (a -> b) -> f a -> f b
  • 7. Functor class Functor f where fmap :: (a -> b) -> f a -> f b
  • 8. Functor class Functor f where fmap :: (a -> b) -> f a -> f b
  • 10. Monad class Functor f where fmap :: (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 11. Monad class Functor f where fmap :: (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 12. Monad class Functor f where fmap :: (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 13. Monad class Functor f where fmap :: (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 14. Monad class Functor f where fmap :: (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 15. Monad class Functor f where fmap :: (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 16. Monad class Functor f where fmap :: (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 17. Monad class Functor f where fmap :: (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 18. Monad class Functor f where fmap :: (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 20. Applicative class Functor f where fmap :: (a -> b) -> f a -> f b class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 21. Applicative class Functor f where fmap :: (a -> b) -> f a -> f b class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 22. Applicative class Functor f where fmap :: (a -> b) -> f a -> f b class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 23. Applicative class Functor f where fmap :: (a -> b) -> f a -> f b class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 24. Applicative class Functor f where fmap :: (a -> b) -> f a -> f b class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 25. Applicative class Functor f where fmap :: (a -> b) -> f a -> f b class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 26. Applicative class Functor f where fmap :: (a -> b) -> f a -> f b class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 27. Applicative class Functor f where fmap :: (a -> b) -> f a -> f b class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 28. Applicative class Functor f where fmap :: (a -> b) -> f a -> f b class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 29. Applicative class Functor f where fmap :: (a -> b) -> f a -> f b class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 30. Applicative class Functor f where fmap :: (a -> b) -> f a -> f b class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 31. Applicative class Functor f where fmap :: (a -> b) -> f a -> f b class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 32. Applicative class Functor f where fmap :: (a -> b) -> f a -> f b class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 33. Applicative class Functor f where fmap :: (a -> b) -> f a -> f b class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
  • 35. Applicative class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b liftA2 :: (a -> b -> c) -> f a -> f b -> f c (*>) :: f a -> f b -> f b (<*) :: f a -> f b -> f a
  • 36. Applicative class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b liftA2 :: (a -> b -> c) -> f a -> f b -> f c (*>) :: f a -> f b -> f b (<*) :: f a -> f b -> f a
  • 37. Applicative class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b liftA2 :: (a -> b -> c) -> f a -> f b -> f c (*>) :: f a -> f b -> f b (<*) :: f a -> f b -> f a
  • 38. Applicative class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b liftA2 :: (a -> b -> c) -> f a -> f b -> f c (*>) :: f a -> f b -> f b (<*) :: f a -> f b -> f a
  • 39. Applicative class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b liftA2 :: (a -> b -> c) -> f a -> f b -> f c (*>) :: f a -> f b -> f b (<*) :: f a -> f b -> f a
  • 40. Applicative class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b liftA2 :: (a -> b -> c) -> f a -> f b -> f c (*>) :: f a -> f b -> f b (<*) :: f a -> f b -> f a
  • 41. Applicative class Functor f => Applicative f where pure :: a -> f a (<*>) :: f (a -> b) -> f a -> f b liftA2 :: (a -> b -> c) -> f a -> f b -> f c (*>) :: f a -> f b -> f b (<*) :: f a -> f b -> f a
  • 43. Types newtype Nickname = Nickname { getNickname :: String } newtype Age = Age { getAge :: Int } data User = User Nickname Age > :t User User :: Nickname -> Age -> User
  • 44. As a function readNickname :: Nickname readAge :: Age readUser :: User readUser = User readNickname readAge
  • 45. With a context readNickname' :: IO Nickname readAge' :: IO Age
  • 46. Using Monad readNickname' :: IO Nickname readAge' :: IO Age readUserM :: IO User readUserM = do nickname <- readNickname' age <- readAge' return $ User nickname age
  • 47. Using Applicative readNickname' :: IO Nickname readAge' :: IO Age readUserA :: IO User readUserA = pure User <*> readNickname' <*> readAge'
  • 48. readNickname' :: IO Nickname readAge' :: IO Age readUserA :: IO User readUserA = User <$> readNickname' <*> readAge' Using Applicative
  • 49. readNickname' :: IO Nickname readAge' :: IO Age readUserA :: IO User readUserA = User <$> readNickname' <*> readAge' Using Applicative
  • 50. An infix synonym for 'fmap' (<$>) :: Functor f => (a -> b) -> f a -> f b (<$>) = fmap
  • 51. Function vs Applicative readNickname :: Nickname readAge :: Age User readNickname readAge readNickname' :: IO Nickname readAge' :: IO Age User <$> readNickname' <*> readAge'
  • 52. Applicative vs Monad readNickname' :: IO Nickname readNickname' = do putStrLn "Your nickname:" str <- getLine if length str > 0 then return $ Nickname str else error "Nickname can't be empty" readAge' :: IO Age readAge' = do putStrLn "Your age:" fmap (Age . read) getLine
  • 53. Applicative vs Monad readUserA :: IO User readUserA = User <$> readNickname' <*> readAge' readUserM :: IO User readUserM = do nickname <- readNickname' age <- readAge' return $ User nickname age
  • 55. Why ?
  • 59. When we need ● Context-free validation/parsing/transformation/optimization/... ● Parallel computation ● Traverlable ● Easier to compose than Monads ● When we can’t / don’t want to create Monad because of extra laws
  • 63. Example: Validation ● Option ● Try ● Either ● ...
  • 64. Example: Validation data Either a b = Left a | Right b
  • 65. Example: Validation validateNickname :: String -> Either [String] Nickname validateNickname str | size < 1 = Left [ "Nickname must have at least 1 character" ] | size > 10 = Left [ "Nickname must have at most 10 characters" ] | otherwise = Right $ Nickname str where size = Data.List.length str validateAge :: Int -> Either [String] Age validateAge val | val < 0 = Left [ "Minimal age is 0" ] | val > 150 = Left [ "Maximal age is 150" ] | otherwise = Right $ Age val
  • 66. Example: Validation validateUser :: String -> Int -> Either [String] User validateUser nickname age = User <$> (validateNickname nickname) <*> (validateAge age)
  • 68. Example: Validation > validateUser "" 200 Left ["Nickname must have at least 1 character"]
  • 69. Example: Validation > validateUser "" 200 Left ["Nickname must have at least 1 character"] > validateUser "john" 200
  • 70. Example: Validation > validateUser "" 200 Left ["Nickname must have at least 1 character"] > validateUser "john" 200 Left ["Maximal age is 150"]
  • 71. Example: Validation > validateUser "" 200 Left ["Nickname must have at least 1 character"] > validateUser "john" 200 Left ["Maximal age is 150"] > validateUser "john" 20 Right (User (Nickname {getNickname = "john"}) (Age {getAge = 20}))
  • 72. Example: Validation data Either a b = Left a | Right b
  • 73. Example: Validation data Either a b = Left a | Right b -- fail fast
  • 74. Example: Validation import Data.Validation data Validation err a = Failure err | Success a data Either a b = Left a | Right b
  • 75. Example: Validation ● A data-type like Either but with an accumulating Applicative ● The Validation data type is isomorphic to Either ● An applicative functor that is not a monad
  • 76. Example: Validation ● A data-type like Either but with an accumulating Applicative ● The Validation data type is isomorphic to Either ● An applicative functor that is not a monad
  • 77. Example: Validation validateNicknameA :: String -> Validation (NonEmpty String) Nickname validateNicknameA str | size < 1 = Failure $ "Nickname must have at least 1 character" :| [] | size > 10 = Failure $ "Nickname must have at most 10 characters" :| [] | otherwise = Success $ Nickname str where size = Data.List.length str validateAgeA :: Int -> Validation (NonEmpty String) Age validateAgeA val | val < 0 = Failure $ "Minimal age is 0" :| [] | val > 150 = Failure $ "Maximal age is 150" :| [] | otherwise = Success $ Age val
  • 78. Example: Validation validateUserA :: String -> Int -> Validation (NonEmpty String) User validateUserA nickname age = User <$> (validateNicknameA nickname) <*> (validateAgeA age)
  • 80. Example: Validation > validateUserA "" 200 Failure ("Nickname must have at least 1 character" :| ["Maximal age is 150"])
  • 81. Example: Validation > validateUserA "" 200 Failure ("Nickname must have at least 1 character" :| ["Maximal age is 150"]) > validateUserA "john" 20 Success (User (Nickname {getNickname = "john"}) (Age {getAge = 20}))
  • 82. Either vs Validation instance Applicative (Either e) where pure = Right Left e <*> _ = Left e Right f <*> r = fmap f r instance Applicative (Validation err) where pure = Success Failure e1 <*> b = Failure $ case b of Failure e2 -> e1 <> e2 Success _ -> e1 Success _ <*> Failure e2 = Failure e2 Success f <*> Success a = Success (f a)
  • 83. Example: haxl ● batch multiple requests to the same data source ● request data from multiple data sources concurrently ● cache previous requests ● memoize computations numCommonFriends x y = length <$> (intersect <$> friendsOf x <*> friendsOf y)
  • 84. Example: Composition readValidNickname :: IO (Maybe Nickname) readValidNickname = do putStrLn "Your name:" str <- getLine if length str > 0 then return $ Just $ Nickname str else return Nothing readValidAge :: IO (Maybe Age) readValidAge = do putStrLn "Your age:" str <- getLine return $ fmap Age $ readMaybe str
  • 85. Example: Composition readValidUserM :: IO (Maybe User) readValidUserM = runMaybeT $ do nickname <- MaybeT readValidNickname age <- MaybeT readValidAge return $ User nickname age
  • 86. Example: Composition readValidUserA :: IO (Maybe User) readValidUserA = unComp1 (User <$> (Comp1 readValidNickname) <*> (Comp1 readValidAge))
  • 87. Example: Composition readValidUserA :: IO (Maybe User) readValidUserA = unComp1 (User <$> (Comp1 readValidNickname) <*> (Comp1 readValidAge)) newtype (:.:) (f :: k2 -> Type) (g :: k1 -> k2) (p :: k1) = Comp1 { unComp1 :: f (g p) }
  • 88. Example: Composition newtype (:.:) (f :: k2 -> Type) (g :: k1 -> k2) (p :: k1) = Comp1 { unComp1 :: f (g p) } instance (Applicative f, Applicative g) => Applicative (f :.: g) where pure x = Comp1 (pure (pure x)) Comp1 f <*> Comp1 x = Comp1 (liftA2 (<*>) f x) liftA2 f (Comp1 x) (Comp1 y) = Comp1 (liftA2 (liftA2 f) x y)
  • 89. Example: Free data Field a = StringField Name Doc | IntField Name Doc | BoolField Name Doc | ObjectField Name Doc (Ap Field a)
  • 90. Example: Free type Dsl a = Ap Field a string :: Name -> Doc -> Dsl String string n d = liftAp $ StringField n d int :: Name -> Doc -> Dsl Int int n d = liftAp $ IntField n d bool :: Name -> Doc -> Dsl Bool bool n d = liftAp $ BoolField n d object :: Name -> Doc -> Dsl a -> Dsl a object n d a = liftAp $ ObjectField n d a
  • 91. Example: Free data User = User String Int Bool data Comment = Comment String User user :: Dsl User user = User <$> string "name" "user's name" <*> int "age" "user's age" <*> bool "active" "is active" comment :: Dsl Comment comment = Comment <$> string "title" "short desc" <*> object "creator" "who created the comment" user
  • 93. Example: Free genDoc :: Int -> Field a -> [String] genDoc indent (StringField n d) = [printf "%*s- %s : string - %s" indent "" n d] genDoc indent (IntField n d) = [printf "%*s- %s : int - %s" indent "" n d] genDoc indent (BoolField n d) = [printf "%*s- %s : bool - %s" indent "" n d] genDoc indent (ObjectField n d m) = asString : nested where asString = printf "%*s- %s : obj - %s" indent "" n d nested = runAp_ (genDoc $ indent + 2) m
  • 94. Example: Free printDoc :: IO () printDoc = mapM_ putStrLn lines where lines = runAp_ (genDoc 0) comment - title : string - short desc - creator : obj - creator of the comment - name : string - user's name - age : int - user's age - active : bool - is active
  • 95. Example: Free ● JSON, XML, ... <-> Model ● Transformation (context-free) ● … (context-free)