Tomáš Petříček, 309 (3rd floor)
petricek@d3s.mff.cuni.cz
https://tomasp.net | @tomaspetricek
https://d3s.mff.cuni.cz/people/tomaspetricek/
More programming language research in Prague!
Ask about reading group!
Do a PL project or thesis!
Join us for a PhD?
// Random number generators
let rnd = Random()
rnd.Next()
// Get the current time
System.DateTime.Now
// Throw an exception
raise "Something went wrong"
// Write to a file
File.WriteAllText(
"/tmp/test.txt", "Hello!")
// Use mutable state
let mutable counter = 0
counter <- counter + 1
Sooner or later, you need to do them!
Communicating with the outside (network, files, input/output)
Expressing things on the inside (threads, mutable state, non-determinism, exceptions)
a -> Maybe b
a -> State b
a -> IO b
a -> State (Maybe b)
a -> Maybe (State b)
Wrap another monad to produce a new one
Works but not great...
Only some combinations
Not an automatic process
Code becomes ugly
Given a variable context \(\Gamma\), an expression \(e\) has a type \(\tau\).
Explain idea in a simple \(\lambda\)-calculus language
Ignore practical aspects like type inference!
Derivation rule for each expression
Expression has a type if there is a derivation
Does not specify
type inference!
They are quite tedious to write by hand!
Adds effect annotations
Added to expression and function type
Var access & lambda creation are pure
Application unions
all effects
Effect handlers can be defined and handled like exceptions
Here just print
and get
Types of Get
and Print
introduce get
and print
Effect annotations combined using union!
(Moggi, 1991)
Monads can be used to model the semantics of side-effects
Two tiny languages
One with built-in effects
One with effects as feature
A category \(\mathcal{C}\) consists of objects \(obj(\mathcal{C})\) and arrows \(arr(\mathcal{C})\) between objects, i.e. \(f : A \rightarrow B\) where \(A, B \in obj(\mathcal{C})\) with:
Arrow composition
Given \(f : A \rightarrow B, g : B \rightarrow C\), there is \(f\circ g:A \rightarrow C\).
Associativity
Given \(f, g, h\), it holds that \((f\circ g)\circ h = f\circ (g\circ h)\)
Identity arrow for all \(B\)
\(id_B : B \rightarrow B\) such that \(id_B \circ f = f\) and \(g \circ id_B = g\)
Arrow composition is function composition!
Haskell's isZero.fst
becomes \(\textit{fst}\,\circ\textit{isZero}\)
What is the meaning of a+b
?
\(\qquad a\!:\!int,b\!:\!int \;\vdash\, a+b\!:\!int\)
Arrow or morphism between two objects:
\(\qquad int\times int\rightarrow int\)
Yes, you can read this as a function too...
What is the meaning of \(e\)?
\(\qquad v_1\!:\!\tau_1,\ldots,v_n\!:\!\tau_n\vdash e : \tau\)
Arrow or morphism between two objects:
\(\qquad \tau_1\times\ldots\times\tau_n \rightarrow \tau\)
Maps (categorical) product of inputs to output
Basics map nicely
Variable access is
identity, composition
is composition
But more is needed
Cartesian Closed Categories
But what if there are side-effects?
\(\qquad v_1\!:\!\tau_1,\ldots,v_n\!:\!\tau_n\vdash e : \tau \htmlStyle{color:#8A003B;}{ \,\&\, s}\)
The result is wrapped with a monad \(\htmlStyle{color:#8A003B;}{M}\)!
\(\qquad \tau_1\times\ldots\times\tau_n \rightarrow \htmlStyle{color:#8A003B;}{M}\,\tau\)
"Monad is just a monoid in the category of endofunctors. What is the problem?"
Given a category \(\mathcal{C}\), a monad is a functor \(\htmlStyle{color:#8A003B;}{M} : \mathcal{C} \rightarrow \mathcal{C}\)
together with mappings (or natural transformations):
\(\eta_\tau : \tau \rightarrow \htmlStyle{color:#8A003B;}{M}(\tau)\)
\((-)^*\) which turns an arrow \(f : \tau_1 \rightarrow \htmlStyle{color:#8A003B;}{M}(\tau_2)\)
into an arrow \(f^* : \htmlStyle{color:#8A003B;}{M}(\tau_1) \rightarrow \htmlStyle{color:#8A003B;}{M}(\tau_2)\)
Monad (functor) wraps the output type
Unit and bind is what we need to compose!
// Reading global state
System.DateTime.Now
// Data-flow computations
(x + prev x) / 2
// Implicit parameters
let foo() = ?x + 1
let ?x = 1 in foo()
// Game of life
let this = (* am I alive *)
let nbr = (* # of neighbours *)
(this && (nbr = 2 || nbr = 3))
|| (not this && nbr = 3)
Reader monad is product comonad
a -> M b
a -> (s -> b)
a * s -> b
C a -> b
Other context-related problems
Given a category \(\mathcal{C}\), a monad is a functor \(\htmlStyle{color:#8A003B;}{M} : \mathcal{C} \rightarrow \mathcal{C}\)
together with mappings (or natural transformations):
\(\eta_\tau : \tau \rightarrow \htmlStyle{color:#8A003B;}{M}(\tau)\)
\((-)^*\) which turns an arrow \(f : \tau_1 \rightarrow \htmlStyle{color:#8A003B;}{M}(\tau_2)\)
into an arrow \(f^* : \htmlStyle{color:#8A003B;}{M}(\tau_1) \rightarrow \htmlStyle{color:#8A003B;}{M}(\tau_2)\)
Given a category \(\mathcal{C}\), a comonad is a functor \(\htmlStyle{color:#8A003B;}{C} : \mathcal{C} \rightarrow \mathcal{C}\)
together with mappings (or natural transformations):
\(\mu_\tau : \htmlStyle{color:#8A003B;}{C}(\tau) \rightarrow \tau\)
\((-)^*\) which turns an arrow \(f : \htmlStyle{color:#8A003B;}{C}(\tau_1) \rightarrow \tau_2\)
into an arrow \(f^* : \htmlStyle{color:#8A003B;}{C}(\tau_1) \rightarrow \htmlStyle{color:#8A003B;}{C}(\tau_2)\)
Monad (functor) wraps the input type
Variable context handling becomes tricky!
Adds coeffect annotations
Variable access is pure
Lambda combines available contexts
Application becomes
a bit tricky!
Derivations in coeffect playground
Two extra operations
Composition (multipication)
Split context into two (requires max)
Merge two contexts (requires min)
Languages and applications with effects, coeffects & capabilities
Semantics of interactive programming systems
Types for data science scripting in Python or R
Effects and Coeffects
Tomáš Petříček, 309 (3rd floor)
petricek@d3s.mff.cuni.cz
https://tomasp.net | @tomaspetricek
https://d3s.mff.cuni.cz/teaching/nprg077