Last time: Overloading val (=) : {E:EQ} → E.t → E.t → bool 1/ 52
This time: monads (etc.) = > > 2/ 52
What do monads give us? A general approach to implementing custom effects A reusable interface to computation A way to structure effectful programs in a functional language 3/ 52
Effects 4/ 52
What’s an effect? An effect is anything a function does besides mapping inputs to outputs. If an expression M evaluates to a value V and changing let x = M let x = V to in N in N changes the behaviour then M also performs effects. 5/ 52
Example effects Effects available in OCaml Effects unavailable in OCaml (An effect is anything other than mapping inputs to outputs.) 6/ 52
Example effects Effects available in OCaml Effects unavailable in OCaml (higher-order) state r := f; !r () (An effect is anything other than mapping inputs to outputs.) 6/ 52
Example effects Effects available in OCaml Effects unavailable in OCaml (higher-order) state r := f; !r () exceptions raise Not_found (An effect is anything other than mapping inputs to outputs.) 6/ 52
Example effects Effects available in OCaml Effects unavailable in OCaml (higher-order) state r := f; !r () exceptions raise Not_found I/O of various sorts input_byte stdin (An effect is anything other than mapping inputs to outputs.) 6/ 52
Example effects Effects available in OCaml Effects unavailable in OCaml (higher-order) state r := f; !r () exceptions raise Not_found I/O of various sorts input_byte stdin concurrency (interleaving) Gc.finalise v f (An effect is anything other than mapping inputs to outputs.) 6/ 52
Example effects Effects available in OCaml Effects unavailable in OCaml (higher-order) state r := f; !r () exceptions raise Not_found I/O of various sorts input_byte stdin concurrency (interleaving) Gc.finalise v f non-termination let rec f x = f x (An effect is anything other than mapping inputs to outputs.) 6/ 52
Example effects Effects available in OCaml Effects unavailable in OCaml (higher-order) state non-determinism r := f; !r () amb f g h exceptions raise Not_found I/O of various sorts input_byte stdin concurrency (interleaving) Gc.finalise v f non-termination let rec f x = f x (An effect is anything other than mapping inputs to outputs.) 6/ 52
Example effects Effects available in OCaml Effects unavailable in OCaml (higher-order) state non-determinism r := f; !r () amb f g h exceptions first-class continuations raise Not_found escape x in e I/O of various sorts input_byte stdin concurrency (interleaving) Gc.finalise v f non-termination let rec f x = f x (An effect is anything other than mapping inputs to outputs.) 6/ 52
Example effects Effects available in OCaml Effects unavailable in OCaml (higher-order) state non-determinism r := f; !r () amb f g h exceptions first-class continuations raise Not_found escape x in e I/O of various sorts polymorphic state input_byte stdin r := "one"; r := 2 concurrency (interleaving) Gc.finalise v f non-termination let rec f x = f x (An effect is anything other than mapping inputs to outputs.) 6/ 52
Example effects Effects unavailable in OCaml Effects available in OCaml non-determinism (higher-order) state amb f g h r := f; !r () first-class continuations exceptions escape x in e raise Not_found polymorphic state I/O of various sorts r := "one"; r := 2 input_byte stdin checked exceptions concurrency (interleaving) IOError − − − − → bool Gc.finalise v f int non-termination let rec f x = f x (An effect is anything other than mapping inputs to outputs.) 6/ 52
Capturing effects in the types Some languages capture effects in the type system. We might have two function arrows: a pure arrow a → b an effectful arrow (or family of arrows) a ⇝ b and combinators for combining effectful functions composeE : ( a ⇝ b ) → ( b ⇝ c ) → ( a ⇝ c ) ignoreE : ( a ⇝ b ) → ( a ⇝ unit ) pairE : ( a ⇝ b ) → ( c ⇝ d ) → ( a × c ⇝ b × d ) liftPure : ( a → b ) → ( a ⇝ b ) 7/ 52
Separating application and performing effects Alternative approach Decompose effectful arrows into pure functions and computations becomes a → T b a ⇝ b 8/ 52
Monads ( let x = e in . . . ) 9/ 52
Programming with monads An imperative program let id = !counter in let () = counter := id + 1 in string_of_int id A monadic program get = fun id → > > put (id + 1) > = fun () → > return ( string_of_int id) 10/ 52
Monads module type MONAD = sig type ’a t val return : ’a → ’a t = ) : ’a t → (’a → ’b t) → ’b t val ( > > end let return {M:MONAD} x = M.return x = ) {M:MONAD} m k = M.( > = ) m k let ( > > > 11/ 52
Monads module type MONAD = sig type ’a t val return : ’a → ’a t val ( > = ) : ’a t → (’a → ’b t) → ’b t > end let return {M:MONAD} x = M.return x let ( > = ) {M:MONAD} m k = M.( > = ) m k > > Laws : return v > = k ≡ k v > v > > = return ≡ v (m > = f) > = g ≡ m > = (fun x → f x > = g) > > > > 11/ 52
Monad laws: intuition 12/ 52
Monad laws: intuition return v > = k ≡ k v > ≡ let x = v in M M[x:=v] 12/ 52
Monad laws: intuition return v > > = k ≡ k v ≡ let x = v in M M[x:=v] v > > = return ≡ v ≡ let x = M in x M 12/ 52
Monad laws: intuition return v > = k ≡ k v > ≡ let x = v in M M[x:=v] v > = return ≡ > v ≡ let x = M in x M (m > = f) > = g ≡ m > = (fun x → f x > = g) > > > > let y = L in let x = (let y = L in M) ≡ let x = M in in N N 12/ 52
Example: a state monad module type STATE = sig type state type ’a t module Monad : MONAD with type ’a t = ’a t val get : state t val put : state → unit t val runState : ’a t → state → state * ’a end implicit module Monad_of_state {S:STATE} = S.Monad 13/ 52
Example: a state monad module type STATE = sig type state type ’a t module Monad : MONAD with type ’a t = ’a t val get : state t val put : state → unit t val runState : ’a t → state → state * ’a end type ’a t = state → state * ’a let return v s = (s, v) 14/ 52
Example: a state monad module type STATE = sig type state type ’a t module Monad : MONAD with type ’a t = ’a t val get : state t val put : state → unit t val runState : ’a t → state → state * ’a end type ’a t = state → state * ’a = ) m k s = let s’, a = m s in k a s’ let ( > > 15/ 52
Example: a state monad module type STATE = sig type state type ’a t module Monad : MONAD with type ’a t = ’a t val get : state t val put : state → unit t val runState : ’a t → state → state * ’a end type ’a t = state → state * ’a let get s = (s, s) 16/ 52
Example: a state monad module type STATE = sig type state type ’a t module Monad : MONAD with type ’a t = ’a t val get : state t val put : state → unit t val runState : ’a t → state → state * ’a end type ’a t = state → state * ’a let put s’ _ = (s’, ()) 17/ 52
Example: a state monad module type STATE = sig type state type ’a t module Monad : MONAD with type ’a t = ’a t val get : state t val put : state → unit t val runState : ’a t → state → state * ’a end type ’a t = state → state * ’a let runState m init = m init 18/ 52
Example: a state monad module type STATE = sig type state type ’a t module Monad : MONAD with type ’a t = ’a t val get : state t val put : state → unit t val runState : ’a t → state → state * ’a end module State (S : sig type t end) = struct type state = S.t type ’a t = state -> state * ’a module Monad = struct type ’a t = state → state * ’a let return v s = (s, v) let ( > = ) m k s = let s’, a = m s in k a s’ > end let get s = (s, s) let put s’ _ = (s’, ()) let runState m init = m init end 19/ 52
Example: a state monad type ’a tree = Empty : ’a tree | Tree : ’a tree * ’a * ’a tree → ’a tree implicit module IState = State (struct type t = int end) let fresh_name : string IState.t = = fun i → get > > = fun () → put (i + 1) > > return (Printf.sprintf "x%d" i) let rec label_tree : ’a tree → string tree IState.t = function Empty → return Empty | Tree (l, v, r) → = fun l → label_tree l > > = fun name → fresh_name > > label_tree r > = fun r → > return (Tree (l, name , r)) 20/ 52
State satisfies the monad laws return v > > = k 21/ 52
State satisfies the monad laws return v > > = k ≡ (definition of return, > =) > fun s → let s’, a = (fun s → (s, v)) s in k a s’ 21/ 52
State satisfies the monad laws return v > > = k ≡ (definition of return, > =) > fun s → let s’, a = (fun s → (s, v)) s in k a s’ ≡ ( β ) fun s → let s’, a = (s, v) in k a s’ 21/ 52
Recommend
More recommend