Title: FpSoup November 2004 Monads and IO
1Fp-Soup November
2004Monads and IO
- Simon Thompson
- S.J.Thompson_at_kent.ac.uk
2Outline
- Effects in functional programming languages
- Generalised functions and the Monad interface.
- Modelling vs real effects
3Pure computation and effects
- Values and nothing else.
- process String -gt Result
- process will give a single result for every input
string. - Examples of processing
- parsing multiple / no results, exceptions,
symbol table, - file manipulation IO, operating system
interface. - calculation update in place, stateful,
4How to add effects?
- No effects allowed.
- No escape from the ghetto.
- Allow expressions to have side-effects.
- Perfectly possible the LISP and ML solution.
- All expressions potentially tainted.
- Completely changes intuitive and formal
semantics. - Controlled access to effects.
- Haskell monads
- Clean uniqueness types
5Controlling effects
- Access to effects only through a particular sort
of interface. - Crucial insight generalised functions
- becomes
- a -gt b a -gt M b
6Composition and binding
- (a -gt M b) -gt (b -gt M c) -gt (a -gt M c)
- M b -gt (b -gt M c) -gt M c
7The Monad interface
- return a -gt M a
- (gtgt) M b -gt (b -gt M c) -gt M c
8What is missing?
- Once in the monad (M a) you cant get out no
function - escape M a -gt a
- although can collapse
- join M (M a) -gt M a
9Exercises
- Exercise using return and gtgt define
- comp (a -gt M b) -gt (b -gt M c) -gt (a -gt M c)
- join M (M a) -gt M a
- liftM (a -gt b) -gt (M a -gt M b)
- Exercise using comp and return define gtgt
- Exercise the composition operator, comp, is
associative and return is its identity what does
these facts imply about the gtgt operator and
return ?
10Recap
- A generalised function has type a -gt M b
- We can think of M a as the type of computations
of a return a value, but along the way perform
some actions. - The interface
- return a -gt M a
- (gtgt) M b -gt (b -gt M c) -gt M c
- allows composition of computations / generalised
functions. Cant combine computations
arbitrarily.
11Modelling versus real effects
- Non-determinism, exceptions, side effects,
input/output and many other effects can be
modelled in a functional language - denotational semantics in reverse.
- Can also hard wire the effects into an
implementation monads as a way of incorporating
real effects into a functional language . - without compromising the whole language.
12Modelling effects
Just a Nothing
13Simple exceptions
- return a -gt M a
- (gtgt) M b -gt (b -gt M c) -gt M c
- data Maybe a Just a Nothing
return v x gtgt f Just v case
x of Just y -gt f y
Nothing -gt Nothing
14Simple exceptions
- No total function from Maybe a to a.
- Explicit sequencing exception in x will be
seen, even if f is a lazy function. - Also has a zero Nothing.
f
return v x gtgt f Just v case
x of Just y -gt f y
Nothing -gt Nothing
15Exercises
16Haskell classes and instances
- class Monad a where
- return a -gt M a
- (gtgt) M b -gt (b -gt M c) -gt M c
- instance Monad Maybe where
- return v Just v
- x gtgt f case x of
- Just y -gt f y
- Nothing -gt Nothing
17Haskell 98 wrapping up instances
- data State a b State (a -gt (a , b))
- instance Monad (State a)
- where
- return x
- State (\st -gt (st,x))
- (State trans) gtgt f
- State (\st -gt let (newSt,y) trans st
- (State newTrans) f y
- innewTrans newSt)
18The value of the interface
- Safety preserves the integrity of the
representation sequencing ensures single
threading. - Readability can hide the details of e.g. state
manipulation behind the interface. - Malleability can change the monadic
implementation add / remove / reconfigure the
various effects.
19Readability
Generate an integer gen M Int Problem
generate two integers and return their sum.
- gen gtgt f
- where
- f n gen gtgt g
- g m return (nm)
- gen gtgt (\n -gt
- gen gtgt (\m -gt
- return (nm))
do n lt- gen m lt- gen return (nm) n names
the result of a computation, and can be used
later in the computation.
20Computation sum a binary tree
- sumT Tree Int -gt Int
- sumT Nil 0
- sumT (Node n t1 t2)
- n sumT t1 sumT t2
- sumT Tree Int -gt M Int
- sumT Nil return 0
- sumT (Node n t1 t2)
- do num lt- return n
- s1 lt- sumT t1
- s2 lt- sumT t2
- return (nums1s2)
data Tree a Nil Node a (Tree a) (Tree a)
21Variants of the sum
- sumT Tree Int -gt M Int
- sumT Nil return 0
- sumT (Node n t1 t2)
- do num lt- return n
- s1 lt- sumT t1
- s2 lt- sumT t2
- return (nums1s2)
Id same computation as before. State count
the number of nodes record different values
instrument IO output values during traversa
l input extra sum terms write out into a file
data Tree a Nil Node a (Tree a) (Tree a)
22Effects for real the IO monad
- To interact with the real world, need system
support. Haskell provides the IO monad some
functions - putStr String -gt IO ()
- putStrLn String -gt IO ()
- getLine IO String
- readFile FilePath -gt IO String
- writeFile FilePath -gt String -gt IO ()
- interact (String -gt String) -gt IO ()
- print Show a gt a -gt IO ()
- readIO Read a gt String -gt IO a
23Read and sum integers until hit 0
- sumInts IO ()
- sumInts do n lt- getInt
- if n0
- then return 0
- else (do m lt- sumInts
- print (nm))
- How to run an IO program? Evaluate sumInts
as the main expression.
24Further work
- Extensions and variations of the notion of monad
monad with a zero, arrows, - Real-world extensions concurrency, arrays,
state, - Monad transformers how (not) to combine a number
of computational effects in a single monad. - Monads for semantics and compiling original
inspiration.