SlideShare a Scribd company logo
1 of 61
Download to read offline
Toward Monad Transformers
Antoine Leblanc - @nicuveo
Functional Programmers Paris
2015-04-01
Outline
▶ Monads!
▶ Our mission
▶ Transformers
▶ Building RestT
▶ Wrapping up
1 / 34
Introduction
What I Wish I Knew When Learning Haskell
2 / 34
Introduction
What I Wish I Knew When Learning Haskell
1. Don’t read the monad tutorials.
2 / 34
Introduction
What I Wish I Knew When Learning Haskell
1. Don’t read the monad tutorials.
2. No really, don’t read the monad tutorials.
2 / 34
Introduction
What I Wish I Knew When Learning Haskell
1. Don’t read the monad tutorials.
2. No really, don’t read the monad tutorials.
…
2 / 34
Introduction
What I Wish I Knew When Learning Haskell
1. Don’t read the monad tutorials.
2. No really, don’t read the monad tutorials.
…
8. Don’t write monad-analogy tutorials.
2 / 34
Typeclass
class Monad m where
return :: a → m a
(>>=) :: m a → (a → m b) → m b
3 / 34
Typeclass
class Monad m where
return :: a → m a
(>>=) :: m a → (a → m b) → m b
adit.io
3 / 34
Typeclass
class Monad m where
return :: a → m a
(>>=) :: m a → (a → m b) → m b
(>>) :: Monad m ⇒ m a → m b → m b
(>=>) :: Monad m ⇒ (a → m b)
→ (b → m c)
→ (a → m c)
3 / 34
Monad laws
Using (>>=)
return a >>= f ≡ f a
m >>= return ≡ m
(m >>= f) >>= g ≡ m >>= (λx → f x >>= g)
4 / 34
Monad laws
Using (>=>)
return >=> f ≡ f
f >=> return ≡ f
(f >=> g) >=> h ≡ f >=> (g >=> h)
4 / 34
Do notation
do { a ← f ; m } ≡ f >>= λa → m
do { f ; m } ≡ f >> m
do { m } ≡ m
5 / 34
Do sugar
f >>= λa →
g >>= λb →
h >>= λc →
return (a, b, c)
6 / 34
Do sugar
f >>= λa →
g >>= λb →
h >>= λc →
return (a, b, c)
do
a ← f
b ← g
c ← h
return (a, b, c)
6 / 34
ALL TEH MONADS
Maybe getUser :: Id → Maybe User
7 / 34
ALL TEH MONADS
Maybe getUser :: Id → Maybe User
Either a parse :: String → Either Error Value
7 / 34
ALL TEH MONADS
Maybe getUser :: Id → Maybe User
Either a parse :: String → Either Error Value
List allNextTurns :: Board → [Board]
7 / 34
ALL TEH MONADS
Maybe getUser :: Id → Maybe User
Either a parse :: String → Either Error Value
List allNextTurns :: Board → [Board]
IO httpGet :: Url → IO String
7 / 34
ALL TEH MONADS
Maybe getUser :: Id → Maybe User
Either a parse :: String → Either Error Value
List allNextTurns :: Board → [Board]
IO httpGet :: Url → IO String
Reader r runReader :: Reader r a → r → a
7 / 34
ALL TEH MONADS
Maybe getUser :: Id → Maybe User
Either a parse :: String → Either Error Value
List allNextTurns :: Board → [Board]
IO httpGet :: Url → IO String
Reader r runReader :: Reader r a → r → a
Writer w runWriter :: Writer w a → (a, w)
7 / 34
ALL TEH MONADS
Maybe getUser :: Id → Maybe User
Either a parse :: String → Either Error Value
List allNextTurns :: Board → [Board]
IO httpGet :: Url → IO String
Reader r runReader :: Reader r a → r → a
Writer w runWriter :: Writer w a → (a, w)
State s runState :: Reader s a → s → (a, s)
7 / 34
Reader Monad
Reader Green :: ■ → ■
Reader Yellow :: ■ → ■
(>>=) :: ■ → ■
→ (■ → ■ → ■ )
→ ■ → ■
runReader :: ■ → ■ → (■ → ■)
8 / 34
Reader example
data Conf = { color :: Color, size :: Int }
formatter :: String → Reader Conf String
formatter p = do
c ← asks color
s ← asks size
return (undefined) -- TODO
format :: Conf → String → String
format c s = runReader (textFormatter s) c
9 / 34
Writer Monad
Writer Green :: ■ ■
Writer Yellow :: ■ ■
(>>=) :: ■ ■
→ (■ → ■ ■ )
→ ■ ■
runWriter :: ■ ■ → (■ ■)
10 / 34
Writer example
type Log = [String]
type Debug = Writer Log
value :: Int → Debug Int
value x = Writer (x, ["Value"])
plus :: Debug Int → Debug Int → Debug Int
plus x y = do
a ← x
b ← y
Writer (a + b, "Plus")
11 / 34
State Monad
State Green :: ■ → ■ ■
State Yellow :: ■ → ■ ■
(>>=) :: ■ → ■ ■
→ (■ → ■ → ■ ■ )
→ ■ → ■ ■
runState :: ■ → ■ ■
→ (■ → ■ ■) 12 / 34
State Example
data GameInfo = GameInfo {
turn :: Int,
score :: Int
}
skipTurn :: State GameInfo ()
skipTurn = do
t ← gets turn
s ← gets score
put $ GameInfo (t + 1) (s `div` 2)
13 / 34
Outline
▶ Monads
▶ Our mission!
▶ Transformers
▶ Building RestT
▶ Wrapping up
14 / 34
REST client
▶ Authenticate
▶ Issue simple commands
▶ That’s it!
15 / 34
Monadic syntax?
main = run $ do
setServerUrl "http://server.com/api"
setCredentials "guest" "guest"
authenticate
result ← request "server.listMyStuff"
print $ format result
16 / 34
Problem
import Network.HTTP.Conduit
simpleHttp :: String → IO ByteString
17 / 34
Problem
import Network.HTTP.Conduit
simpleHttp :: String → IO ByteString
IO!
17 / 34
Problem
import Network.HTTP.Conduit
simpleHttp :: String → IO ByteString
wait…
17 / 34
Problem
import Network.HTTP.Conduit
simpleHttp :: MonadIO m ⇒
String → m ByteString
…MonadIO?
17 / 34
State in IO
▶ MVar?
▶ IORef?
18 / 34
State in IO
▶ MVar?
▶ IORef?
...add State and Either monads to IO?
18 / 34
Outline
▶ Monads
▶ Our mission
▶ Transformers!
▶ Building RestT
▶ Wrapping up
19 / 34
All the way down
▶ Monad generalization
▶ Extra monad parameter
▶ Monad stacks
20 / 34
Monad → MonadT
data State s a = { ... }
get :: State s s
put :: s → State s ()
Mister
21 / 34
Monad → MonadT
data StateT s m a = { ... }
get :: MonadState s m ⇒ m s
put :: MonadState s m ⇒ s → m ()
MisterT
21 / 34
Lifting
example :: CustomT IO Int
example = do
customStuff 1
lift $ putStrLn "Turtles!"
customStuff 2
22 / 34
Lifting
example :: CustomT (MaybeT IO) Int
example = do
customStuff 1
lift $ lift $ putStrLn "Turtles!"
customStuff 2
22 / 34
Instances
class Monad m ⇒ MonadState s m where
get :: m s
put :: s → m ()
instance MonadState s m ⇒
MonadState s (ReaderT r m) where
get = lift get
put = lift . put
23 / 34
n 2
IO ↔ MonadIO ↔ liftIO
StateT ↔ MonadState ↔ get
ReaderT ↔ MonadReader ↔ ask
WriterT ↔ MonadWriter ↔ tell
ErrorT ↔ MonadError ↔ throwError
24 / 34
Outline
▶ Monads
▶ Our mission
▶ Transformers
▶ Building RestT!
▶ Wrapping up
25 / 34
Handling errors: ErrorT
type ErrorMsg = String
type Result m a = m (Either ErrorMsg a)
type RestT m = ErrorT ErrorMsg m
..
m
.
ErrorT ErrorMsg a
26 / 34
Handling errors: ErrorT
type ErrorMsg = String
type Result m a = m (Either ErrorMsg a)
type RestT m = ErrorT ErrorMsg m
run :: RestT m a → Result m a
run = runErrorT
..
m
.
ErrorT ErrorMsg a
26 / 34
Handling errors: ErrorT
type ErrorMsg = String
type Result m a = m (Either ErrorMsg a)
type RestT m = ErrorT ErrorMsg m
run :: RestT m a → Result m a
run = runErrorT
liftRest :: m a → RestT m a
liftRest = lift
..
m
.
ErrorT ErrorMsg a
26 / 34
Adding session: StateT
type ErrorMsg = String
type Token = String
type Result m a = m (Either ErrorMsg a)
type RestT m = StateT Token (ErrorT ErrorMsg m)
..
m
.
ErrorT ErrorMsg
.
StateT Token a
27 / 34
Adding session: StateT
type ErrorMsg = String
type Token = String
type Result m a = m (Either ErrorMsg a)
type RestT m = StateT Token (ErrorT ErrorMsg m)
run :: Token → RestT m a → Result m a
run t x = runErrorT $ evalStateT x t
..
m
.
ErrorT ErrorMsg
.
StateT Token a
27 / 34
Adding session: StateT
type ErrorMsg = String
type Token = String
type Result m a = m (Either ErrorMsg a)
type RestT m = StateT Token (ErrorT ErrorMsg m)
run :: Token → RestT m a → Result m a
run t x = runErrorT $ evalStateT x t
liftRest :: m a → RestT m a
liftRest = lift . lift
..
m
.
ErrorT ErrorMsg
.
StateT Token a
27 / 34
Dependency injection: ReaderT
type ErrorMsg = String
type Token = String
type Getter m = String → m String
type Result m a = m (Either ErrorMsg a)
type RestT m = ReaderT (Getter m) (StateT Token (ErrorT ErrorMsg m))
..
m
.
ErrorT ErrorMsg
.
StateT Token
.
ReaderT (Getter m) a
28 / 34
Dependency injection: ReaderT
type ErrorMsg = String
type Token = String
type Getter m = String → m String
type Result m a = m (Either ErrorMsg a)
type RestT m = ReaderT (Getter m) (StateT Token (ErrorT ErrorMsg m))
run :: Getter m → Token → RestT m a → Result m a
run g t x = runErrorT $ evalStateT (runReaderT x g) t
..
m
.
ErrorT ErrorMsg
.
StateT Token
.
ReaderT (Getter m) a
28 / 34
Dependency injection: ReaderT
type ErrorMsg = String
type Token = String
type Getter m = String → m String
type Result m a = m (Either ErrorMsg a)
type RestT m = ReaderT (Getter m) (StateT Token (ErrorT ErrorMsg m))
run :: Getter m → Token → RestT m a → Result m a
run g t x = runErrorT $ evalStateT (runReaderT x g) t
liftRest :: m a → RestT m a
liftRest = lift . lift . lift
..
m
.
ErrorT ErrorMsg
.
StateT Token
.
ReaderT (Getter m) a
28 / 34
YAY!
request :: String → RestT m String
request method = do
getter ← ask
token ← get
let q = query method token
liftRest $ getter q
29 / 34
AT LAST!
authenticate :: RestT m ()
authenticate = do
token ← get
unless (null token)
(throwError "already logged in")
answer ← request "getToken"
token ← parse answer
put token
30 / 34
WOOOO!
main = void $ run httpGet emptyToken $ do
authenticate
answer ← request "showMyStuff"
liftIO $ print answer
31 / 34
Outline
▶ Monads
▶ Our mission
▶ Transformers
▶ Building RestT
▶ Wrapping up!
32 / 34
What have we learned today?
▶ Transformers: stack monads.
▶ Combine their powers!
▶ Hide stack details.
33 / 34
This is the end. You are free.
Thank you.
Any questions?
34 / 34

More Related Content

Similar to Toward Haskell Transformers

Csharp4 delegates lambda_and_events
Csharp4 delegates lambda_and_eventsCsharp4 delegates lambda_and_events
Csharp4 delegates lambda_and_eventsAbed Bukhari
 
Go Programming Language (Golang)
Go Programming Language (Golang)Go Programming Language (Golang)
Go Programming Language (Golang)Ishin Vin
 
2.overview of c++ ________lecture2
2.overview of c++  ________lecture22.overview of c++  ________lecture2
2.overview of c++ ________lecture2Warui Maina
 
Kamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, codeKamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, codeKamil Witecki
 
Final tagless vs free monad
Final tagless vs free monadFinal tagless vs free monad
Final tagless vs free monadAlexander Granin
 
Microcontroller lec 3
Microcontroller  lec 3Microcontroller  lec 3
Microcontroller lec 3Ibrahim Reda
 
Clean code _v2003
 Clean code _v2003 Clean code _v2003
Clean code _v2003R696
 
A closure ekon16
A closure ekon16A closure ekon16
A closure ekon16Max Kleiner
 
The Goal and The Journey - Turning back on one year of C++14 Migration
The Goal and The Journey - Turning back on one year of C++14 MigrationThe Goal and The Journey - Turning back on one year of C++14 Migration
The Goal and The Journey - Turning back on one year of C++14 MigrationJoel Falcou
 
BKK16-503 Undefined Behavior and Compiler Optimizations – Why Your Program St...
BKK16-503 Undefined Behavior and Compiler Optimizations – Why Your Program St...BKK16-503 Undefined Behavior and Compiler Optimizations – Why Your Program St...
BKK16-503 Undefined Behavior and Compiler Optimizations – Why Your Program St...Linaro
 
Legacy lambda code
Legacy lambda codeLegacy lambda code
Legacy lambda codePeter Lawrey
 
Intermediate code generation
Intermediate code generationIntermediate code generation
Intermediate code generationAkshaya Arunan
 
C_Programming_Language_tutorial__Autosaved_.pptx
C_Programming_Language_tutorial__Autosaved_.pptxC_Programming_Language_tutorial__Autosaved_.pptx
C_Programming_Language_tutorial__Autosaved_.pptxLikhil181
 
Hacking parse.y (RubyConf 2009)
Hacking parse.y (RubyConf 2009)Hacking parse.y (RubyConf 2009)
Hacking parse.y (RubyConf 2009)ujihisa
 

Similar to Toward Haskell Transformers (20)

MTL Versus Free
MTL Versus FreeMTL Versus Free
MTL Versus Free
 
Csharp4 delegates lambda_and_events
Csharp4 delegates lambda_and_eventsCsharp4 delegates lambda_and_events
Csharp4 delegates lambda_and_events
 
Go Programming Language (Golang)
Go Programming Language (Golang)Go Programming Language (Golang)
Go Programming Language (Golang)
 
Legacy is Good
Legacy is GoodLegacy is Good
Legacy is Good
 
2.overview of c++ ________lecture2
2.overview of c++  ________lecture22.overview of c++  ________lecture2
2.overview of c++ ________lecture2
 
Kamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, codeKamil witecki asynchronous, yet readable, code
Kamil witecki asynchronous, yet readable, code
 
MP in Clojure
MP in ClojureMP in Clojure
MP in Clojure
 
Final tagless vs free monad
Final tagless vs free monadFinal tagless vs free monad
Final tagless vs free monad
 
09. haskell Context
09. haskell Context09. haskell Context
09. haskell Context
 
LBM 1
LBM 1LBM 1
LBM 1
 
Microcontroller lec 3
Microcontroller  lec 3Microcontroller  lec 3
Microcontroller lec 3
 
Clean code _v2003
 Clean code _v2003 Clean code _v2003
Clean code _v2003
 
A closure ekon16
A closure ekon16A closure ekon16
A closure ekon16
 
The Goal and The Journey - Turning back on one year of C++14 Migration
The Goal and The Journey - Turning back on one year of C++14 MigrationThe Goal and The Journey - Turning back on one year of C++14 Migration
The Goal and The Journey - Turning back on one year of C++14 Migration
 
Csharp4 generics
Csharp4 genericsCsharp4 generics
Csharp4 generics
 
BKK16-503 Undefined Behavior and Compiler Optimizations – Why Your Program St...
BKK16-503 Undefined Behavior and Compiler Optimizations – Why Your Program St...BKK16-503 Undefined Behavior and Compiler Optimizations – Why Your Program St...
BKK16-503 Undefined Behavior and Compiler Optimizations – Why Your Program St...
 
Legacy lambda code
Legacy lambda codeLegacy lambda code
Legacy lambda code
 
Intermediate code generation
Intermediate code generationIntermediate code generation
Intermediate code generation
 
C_Programming_Language_tutorial__Autosaved_.pptx
C_Programming_Language_tutorial__Autosaved_.pptxC_Programming_Language_tutorial__Autosaved_.pptx
C_Programming_Language_tutorial__Autosaved_.pptx
 
Hacking parse.y (RubyConf 2009)
Hacking parse.y (RubyConf 2009)Hacking parse.y (RubyConf 2009)
Hacking parse.y (RubyConf 2009)
 

Recently uploaded

Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
(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
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
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
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
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.
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
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
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
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
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 

Recently uploaded (20)

Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
(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...
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
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...
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
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...
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
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
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
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
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 

Toward Haskell Transformers

  • 1. Toward Monad Transformers Antoine Leblanc - @nicuveo Functional Programmers Paris 2015-04-01
  • 2. Outline ▶ Monads! ▶ Our mission ▶ Transformers ▶ Building RestT ▶ Wrapping up 1 / 34
  • 3. Introduction What I Wish I Knew When Learning Haskell 2 / 34
  • 4. Introduction What I Wish I Knew When Learning Haskell 1. Don’t read the monad tutorials. 2 / 34
  • 5. Introduction What I Wish I Knew When Learning Haskell 1. Don’t read the monad tutorials. 2. No really, don’t read the monad tutorials. 2 / 34
  • 6. Introduction What I Wish I Knew When Learning Haskell 1. Don’t read the monad tutorials. 2. No really, don’t read the monad tutorials. … 2 / 34
  • 7. Introduction What I Wish I Knew When Learning Haskell 1. Don’t read the monad tutorials. 2. No really, don’t read the monad tutorials. … 8. Don’t write monad-analogy tutorials. 2 / 34
  • 8. Typeclass class Monad m where return :: a → m a (>>=) :: m a → (a → m b) → m b 3 / 34
  • 9. Typeclass class Monad m where return :: a → m a (>>=) :: m a → (a → m b) → m b adit.io 3 / 34
  • 10. Typeclass class Monad m where return :: a → m a (>>=) :: m a → (a → m b) → m b (>>) :: Monad m ⇒ m a → m b → m b (>=>) :: Monad m ⇒ (a → m b) → (b → m c) → (a → m c) 3 / 34
  • 11. Monad laws Using (>>=) return a >>= f ≡ f a m >>= return ≡ m (m >>= f) >>= g ≡ m >>= (λx → f x >>= g) 4 / 34
  • 12. Monad laws Using (>=>) return >=> f ≡ f f >=> return ≡ f (f >=> g) >=> h ≡ f >=> (g >=> h) 4 / 34
  • 13. Do notation do { a ← f ; m } ≡ f >>= λa → m do { f ; m } ≡ f >> m do { m } ≡ m 5 / 34
  • 14. Do sugar f >>= λa → g >>= λb → h >>= λc → return (a, b, c) 6 / 34
  • 15. Do sugar f >>= λa → g >>= λb → h >>= λc → return (a, b, c) do a ← f b ← g c ← h return (a, b, c) 6 / 34
  • 16. ALL TEH MONADS Maybe getUser :: Id → Maybe User 7 / 34
  • 17. ALL TEH MONADS Maybe getUser :: Id → Maybe User Either a parse :: String → Either Error Value 7 / 34
  • 18. ALL TEH MONADS Maybe getUser :: Id → Maybe User Either a parse :: String → Either Error Value List allNextTurns :: Board → [Board] 7 / 34
  • 19. ALL TEH MONADS Maybe getUser :: Id → Maybe User Either a parse :: String → Either Error Value List allNextTurns :: Board → [Board] IO httpGet :: Url → IO String 7 / 34
  • 20. ALL TEH MONADS Maybe getUser :: Id → Maybe User Either a parse :: String → Either Error Value List allNextTurns :: Board → [Board] IO httpGet :: Url → IO String Reader r runReader :: Reader r a → r → a 7 / 34
  • 21. ALL TEH MONADS Maybe getUser :: Id → Maybe User Either a parse :: String → Either Error Value List allNextTurns :: Board → [Board] IO httpGet :: Url → IO String Reader r runReader :: Reader r a → r → a Writer w runWriter :: Writer w a → (a, w) 7 / 34
  • 22. ALL TEH MONADS Maybe getUser :: Id → Maybe User Either a parse :: String → Either Error Value List allNextTurns :: Board → [Board] IO httpGet :: Url → IO String Reader r runReader :: Reader r a → r → a Writer w runWriter :: Writer w a → (a, w) State s runState :: Reader s a → s → (a, s) 7 / 34
  • 23. Reader Monad Reader Green :: ■ → ■ Reader Yellow :: ■ → ■ (>>=) :: ■ → ■ → (■ → ■ → ■ ) → ■ → ■ runReader :: ■ → ■ → (■ → ■) 8 / 34
  • 24. Reader example data Conf = { color :: Color, size :: Int } formatter :: String → Reader Conf String formatter p = do c ← asks color s ← asks size return (undefined) -- TODO format :: Conf → String → String format c s = runReader (textFormatter s) c 9 / 34
  • 25. Writer Monad Writer Green :: ■ ■ Writer Yellow :: ■ ■ (>>=) :: ■ ■ → (■ → ■ ■ ) → ■ ■ runWriter :: ■ ■ → (■ ■) 10 / 34
  • 26. Writer example type Log = [String] type Debug = Writer Log value :: Int → Debug Int value x = Writer (x, ["Value"]) plus :: Debug Int → Debug Int → Debug Int plus x y = do a ← x b ← y Writer (a + b, "Plus") 11 / 34
  • 27. State Monad State Green :: ■ → ■ ■ State Yellow :: ■ → ■ ■ (>>=) :: ■ → ■ ■ → (■ → ■ → ■ ■ ) → ■ → ■ ■ runState :: ■ → ■ ■ → (■ → ■ ■) 12 / 34
  • 28. State Example data GameInfo = GameInfo { turn :: Int, score :: Int } skipTurn :: State GameInfo () skipTurn = do t ← gets turn s ← gets score put $ GameInfo (t + 1) (s `div` 2) 13 / 34
  • 29. Outline ▶ Monads ▶ Our mission! ▶ Transformers ▶ Building RestT ▶ Wrapping up 14 / 34
  • 30. REST client ▶ Authenticate ▶ Issue simple commands ▶ That’s it! 15 / 34
  • 31. Monadic syntax? main = run $ do setServerUrl "http://server.com/api" setCredentials "guest" "guest" authenticate result ← request "server.listMyStuff" print $ format result 16 / 34
  • 32. Problem import Network.HTTP.Conduit simpleHttp :: String → IO ByteString 17 / 34
  • 33. Problem import Network.HTTP.Conduit simpleHttp :: String → IO ByteString IO! 17 / 34
  • 34. Problem import Network.HTTP.Conduit simpleHttp :: String → IO ByteString wait… 17 / 34
  • 35. Problem import Network.HTTP.Conduit simpleHttp :: MonadIO m ⇒ String → m ByteString …MonadIO? 17 / 34
  • 36. State in IO ▶ MVar? ▶ IORef? 18 / 34
  • 37. State in IO ▶ MVar? ▶ IORef? ...add State and Either monads to IO? 18 / 34
  • 38. Outline ▶ Monads ▶ Our mission ▶ Transformers! ▶ Building RestT ▶ Wrapping up 19 / 34
  • 39. All the way down ▶ Monad generalization ▶ Extra monad parameter ▶ Monad stacks 20 / 34
  • 40. Monad → MonadT data State s a = { ... } get :: State s s put :: s → State s () Mister 21 / 34
  • 41. Monad → MonadT data StateT s m a = { ... } get :: MonadState s m ⇒ m s put :: MonadState s m ⇒ s → m () MisterT 21 / 34
  • 42. Lifting example :: CustomT IO Int example = do customStuff 1 lift $ putStrLn "Turtles!" customStuff 2 22 / 34
  • 43. Lifting example :: CustomT (MaybeT IO) Int example = do customStuff 1 lift $ lift $ putStrLn "Turtles!" customStuff 2 22 / 34
  • 44. Instances class Monad m ⇒ MonadState s m where get :: m s put :: s → m () instance MonadState s m ⇒ MonadState s (ReaderT r m) where get = lift get put = lift . put 23 / 34
  • 45. n 2 IO ↔ MonadIO ↔ liftIO StateT ↔ MonadState ↔ get ReaderT ↔ MonadReader ↔ ask WriterT ↔ MonadWriter ↔ tell ErrorT ↔ MonadError ↔ throwError 24 / 34
  • 46. Outline ▶ Monads ▶ Our mission ▶ Transformers ▶ Building RestT! ▶ Wrapping up 25 / 34
  • 47. Handling errors: ErrorT type ErrorMsg = String type Result m a = m (Either ErrorMsg a) type RestT m = ErrorT ErrorMsg m .. m . ErrorT ErrorMsg a 26 / 34
  • 48. Handling errors: ErrorT type ErrorMsg = String type Result m a = m (Either ErrorMsg a) type RestT m = ErrorT ErrorMsg m run :: RestT m a → Result m a run = runErrorT .. m . ErrorT ErrorMsg a 26 / 34
  • 49. Handling errors: ErrorT type ErrorMsg = String type Result m a = m (Either ErrorMsg a) type RestT m = ErrorT ErrorMsg m run :: RestT m a → Result m a run = runErrorT liftRest :: m a → RestT m a liftRest = lift .. m . ErrorT ErrorMsg a 26 / 34
  • 50. Adding session: StateT type ErrorMsg = String type Token = String type Result m a = m (Either ErrorMsg a) type RestT m = StateT Token (ErrorT ErrorMsg m) .. m . ErrorT ErrorMsg . StateT Token a 27 / 34
  • 51. Adding session: StateT type ErrorMsg = String type Token = String type Result m a = m (Either ErrorMsg a) type RestT m = StateT Token (ErrorT ErrorMsg m) run :: Token → RestT m a → Result m a run t x = runErrorT $ evalStateT x t .. m . ErrorT ErrorMsg . StateT Token a 27 / 34
  • 52. Adding session: StateT type ErrorMsg = String type Token = String type Result m a = m (Either ErrorMsg a) type RestT m = StateT Token (ErrorT ErrorMsg m) run :: Token → RestT m a → Result m a run t x = runErrorT $ evalStateT x t liftRest :: m a → RestT m a liftRest = lift . lift .. m . ErrorT ErrorMsg . StateT Token a 27 / 34
  • 53. Dependency injection: ReaderT type ErrorMsg = String type Token = String type Getter m = String → m String type Result m a = m (Either ErrorMsg a) type RestT m = ReaderT (Getter m) (StateT Token (ErrorT ErrorMsg m)) .. m . ErrorT ErrorMsg . StateT Token . ReaderT (Getter m) a 28 / 34
  • 54. Dependency injection: ReaderT type ErrorMsg = String type Token = String type Getter m = String → m String type Result m a = m (Either ErrorMsg a) type RestT m = ReaderT (Getter m) (StateT Token (ErrorT ErrorMsg m)) run :: Getter m → Token → RestT m a → Result m a run g t x = runErrorT $ evalStateT (runReaderT x g) t .. m . ErrorT ErrorMsg . StateT Token . ReaderT (Getter m) a 28 / 34
  • 55. Dependency injection: ReaderT type ErrorMsg = String type Token = String type Getter m = String → m String type Result m a = m (Either ErrorMsg a) type RestT m = ReaderT (Getter m) (StateT Token (ErrorT ErrorMsg m)) run :: Getter m → Token → RestT m a → Result m a run g t x = runErrorT $ evalStateT (runReaderT x g) t liftRest :: m a → RestT m a liftRest = lift . lift . lift .. m . ErrorT ErrorMsg . StateT Token . ReaderT (Getter m) a 28 / 34
  • 56. YAY! request :: String → RestT m String request method = do getter ← ask token ← get let q = query method token liftRest $ getter q 29 / 34
  • 57. AT LAST! authenticate :: RestT m () authenticate = do token ← get unless (null token) (throwError "already logged in") answer ← request "getToken" token ← parse answer put token 30 / 34
  • 58. WOOOO! main = void $ run httpGet emptyToken $ do authenticate answer ← request "showMyStuff" liftIO $ print answer 31 / 34
  • 59. Outline ▶ Monads ▶ Our mission ▶ Transformers ▶ Building RestT ▶ Wrapping up! 32 / 34
  • 60. What have we learned today? ▶ Transformers: stack monads. ▶ Combine their powers! ▶ Hide stack details. 33 / 34
  • 61. This is the end. You are free. Thank you. Any questions? 34 / 34