last time monads etc
play

Last time: monads (etc.) = > > 1/ 40 This time: - PowerPoint PPT Presentation

Last time: monads (etc.) = > > 1/ 40 This time: applicatives (etc.) 2/ 40 Example effects Effects unavailable in OCaml Effects available in OCaml non-determinism (higher-order) state amb f g h r := f; !r () first-class


  1. Last time: monads (etc.) = > > 1/ 40

  2. This time: applicatives (etc.) ⊗ 2/ 40

  3. 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 Gc. finalise v f int − − − − → bool non-termination let rec f x = f x 3/ 40

  4. Monads, bind and let! An imperative program l e t id = ! counter in l e t () = counter := id + 1 in s t r i n g o f i n t id A monadic program get = fun id → > > put ( id + 1) > = fun () → > r e t u r n ( s t r i n g o f i n t id ) 4/ 40

  5. Type parameters and instantiation parameterised monads monads indexed monads type (’ s, ’t, ’a) t type ’a t type (’e, ’a) t { P } C { Q } let .. in Γ ⊢ M : A ! e 5/ 40

  6. Monadic effect are higher-order E E E composeE : ( a − − → b ) → ( b − − → c ) → ( a − − → c ) E E E pairE : ( a − − → b ) → ( c − − → d ) → ( a × c − − → b × d ) E E E uncurryE : ( a − − → b − − → c ) → ( a × b − − → c ) E liftPure : ( a → b ) → ( a − − → b ) 6/ 40

  7. Higher-order effects with monads v a l uncurryM : ( ’ a → ( ’ b → ’ c t ) t ) → (( ’ a ∗ ’b) → ’ c t ) l e t uncurryM f ( x , y ) = f x > = fun g → > g y 7/ 40

  8. Applicatives ( let . . . and) 8/ 40

  9. Allowing only “static” effects Idea: stop information flowing from one computation into another. Only allow unparameterised computations: E 1 − − → b We can no longer write functions like this: E E E composeE : ( a − − → b ) → ( b − − → c ) → ( a − − → c ) but some useful functions are still possible: E E E pairE static : (1 − − → a ) → (1 − − → b ) → (1 − − → a × b ) 9/ 40

  10. Applicative programs An imperative program l e t x = fresh name () and y = fresh name () in ( x , y ) An applicative program pure ( fun x y → ( x , y )) ⊗ fresh name ⊗ fresh name 10/ 40

  11. Applicatives module type APPLICATIVE = s i g type ’ a t v a l pure : ’ a → ’ a t v a l ( ⊗ ) : ( ’ a → ’b) t → ’ a t → ’b t end 11/ 40

  12. Applicatives module type APPLICATIVE = s i g type ’ a t v a l pure : ’ a → ’ a t v a l ( ⊗ ) : ( ’ a → ’b) t → ’ a t → ’b t end Laws : pure f ⊗ pure v ≡ pure (f v) u ≡ pure id ⊗ u u ⊗ (v ⊗ w) ≡ pure compose ⊗ u ⊗ v ⊗ w v ⊗ pure x ≡ pure (fun f → f x) ⊗ v 11/ 40

  13. = vs ⊗ > > The type of > =: ’a t → (’a → ’b t) → ’b t > ’a → ’b t: a function that builds a computation (Almost) the type of ⊗ : ’a t → (’a → ’b) t → ’b t (’a → ’b) t: a computation that builds a function The actual type of ⊗ : (’a → ’b) t → ’a t → ’b t 12/ 40

  14. Applicative normal forms pure f ⊗ c 1 ⊗ c 2 . . . ⊗ c n pure (fun x 1 x 2 . . . x n → e) ⊗ c 1 ⊗ c 2 . . . ⊗ c n l e t ! x 1 = c 1 and ! x 2 = c 2 . . . and ! x n = c n in e 13/ 40

  15. Applicative normalisation via the laws pure f ⊗ (pure g ⊗ fresh name) ⊗ fresh name 14/ 40

  16. Applicative normalisation via the laws pure f ⊗ (pure g ⊗ fresh name) ⊗ fresh name ≡ (composition law) (pure compose ⊗ pure f ⊗ pure g ⊗ fresh name) ⊗ fresh name 14/ 40

  17. Applicative normalisation via the laws pure f ⊗ (pure g ⊗ fresh name) ⊗ fresh name ≡ (composition law) (pure compose ⊗ pure f ⊗ pure g ⊗ fresh name) ⊗ fresh name ≡ (homomorphism law ( × 2)) pure (compose f g) ⊗ fresh name ⊗ fresh name 14/ 40

  18. Creating applicatives: every monad is an applicative module Applicative of monad (M:MONAD) : APPLICATIVE with type ’ a t = ’ a M. t = s t r u c t type ’ a t = ’ a M. t l e t pure = M. r e t u r n l e t ( ⊗ ) f p = M. ( f > = fun g → > p > = fun q → > r e t u r n ( g q )) end 15/ 40

  19. The state applicative via the state monad module StateA (S : s i g type t end ) : s i g type s t a t e = S . t i n c l u d e APPLICATIVE v a l get : s t a t e t v a l put : s t a t e → u n i t t v a l runState : ’ a t → i n i t : s t a t e → s t a t e ∗ ’ a end = s t r u c t type s t a t e = S . t i n c l u d e Applicative of monad ( State (S )) l e t ( get , put , runState ) = M. ( get , put , runState ) end 16/ 40

  20. Creating applicatives: composing applicatives module Compose (F : APPLICATIVE) (G : APPLICATIVE) : APPLICATIVE with type ’ a t = ’ a G. t F . t = s t r u c t type ’ a t = ’ a G. t F . t l e t pure x = F . pure (G. pure x ) l e t ( ⊗ ) f x = F . ( pure G. ( ⊗ ) ⊗ f ⊗ x ) end 17/ 40

  21. Creating applicatives: the dual applicative module D u a l a p p l i c a t i v e (A: APPLICATIVE) : APPLICATIVE with type ’ a t = ’ a A. t = s t r u c t type ’ a t = ’ a A. t l e t pure = A. pure l e t ( ⊗ ) f x = A. ( pure ( fun y g → g y ) ⊗ x ⊗ f ) end 18/ 40

  22. Composed applicatives are law-abiding pure f ⊗ pure x 19/ 40

  23. Composed applicatives are law-abiding pure f ⊗ pure x ≡ (definition of ⊗ and pure) F.pure ( ⊗ G ) ⊗ F F.pure (G.pure f) ⊗ F F.pure (G.pure x) 19/ 40

  24. Composed applicatives are law-abiding pure f ⊗ pure x ≡ (definition of ⊗ and pure) F.pure ( ⊗ G ) ⊗ F F.pure (G.pure f) ⊗ F F.pure (G.pure x) ≡ (homomorphism law for F ( × 2)) F.pure (G.pure f ⊗ G G.pure x) 19/ 40

  25. Composed applicatives are law-abiding pure f ⊗ pure x ≡ (definition of ⊗ and pure) F.pure ( ⊗ G ) ⊗ F F.pure (G.pure f) ⊗ F F.pure (G.pure x) ≡ (homomorphism law for F ( × 2)) F.pure (G.pure f ⊗ G G.pure x) ≡ (homomorphism law for G) F.pure (G.pure (f x)) 19/ 40

  26. Composed applicatives are law-abiding pure f ⊗ pure x ≡ (definition of ⊗ and pure) F.pure ( ⊗ G ) ⊗ F F.pure (G.pure f) ⊗ F F.pure (G.pure x) ≡ (homomorphism law for F ( × 2)) F.pure (G.pure f ⊗ G G.pure x) ≡ (homomorphism law for G) F.pure (G.pure (f x)) ≡ (definition of pure) pure (f x) 19/ 40

  27. Fresh names, monadically type ’ a t r e e = Empty : ’ a t r e e | Tree : ’ a t r e e ∗ ’ a ∗ ’ a t r e e → ’ a t r e e module I S t a t e = State ( s t r u c t type t = i n t end ) l e t fresh name : s t r i n g I S t a t e . t = get = fun i → > > put ( i + 1) > = fun () → > r e t u r n ( P r i n t f . s p r i n t f ”x%d” i ) l e t rec l a b e l t r e e : ’ a t r e e → s t r i n g t r e e I S t a t e . t = f u n c t i o n Empty → r e t u r n Empty | Tree ( l , v , r ) → l a b e l t r e e l > = fun l → > fresh name = fun name → > > l a b e l t r e e r > = fun r → > r e t u r n ( Tree ( l , name , r )) 20/ 40

  28. Naming as a primitive effect Problem: we cannot write fresh name using the APPLICATIVE interface. l e t fresh name : s t r i n g I S t a t e . t = get = fun i → > > put ( i + 1) > = fun () → > r e t u r n ( P r i n t f . s p r i n t f ”x%d” i ) Solution: introduce it as a primitive effect: module NameA : s i g i n c l u d e APPLICATIVE v a l fresh name : s t r i n g t end = . . . 21/ 40

  29. Traversing with namer l e t rec l a b e l t r e e : ’ a t r e e → s t r i n g t r e e NameA. t = f u n c t i o n Empty → pure Empty | Tree ( l , v , r ) → pure ( fun l name r → Tree ( l , name , r )) ⊗ l a b e l t r e e l ⊗ fresh name ⊗ l a b e l t r e e r 22/ 40

  30. The phantom monoid applicative module type MONOID = s i g type t v a l zero : t v a l (+ +) : t → t → t end module Phantom monoid (M: MONOID) : APPLICATIVE with type ’ a t = M. t = s t r u c t type ’ a t = M. t l e t pure = M. zero l e t ( ⊗ ) = M. ( + +) end 23/ 40

  31. The phantom monoid applicative module type MONOID = s i g type t v a l zero : t v a l (+ +) : t → t → t end module Phantom monoid (M: MONOID) : APPLICATIVE with type ’ a t = M. t = s t r u c t type ’ a t = M. t l e t pure = M. zero l e t ( ⊗ ) = M. ( + +) end Observation: we cannot implement Phantom monoid as a monad. 23/ 40

  32. Applicatives vs monads programs implementations ⊗ = > > = ⊗ > > Some monadic programs are not applicative, e.g. fresh name. Some applicative instances are not monadic, e.g. Phantom monoid. 24/ 40

  33. Guideline: Postel’s law Be conservative in what you do, be liberal in what you accept from others. 25/ 40

  34. Guideline: Postel’s law Be conservative in what you do, be liberal in what you accept from others. Conservative in what you do: use applicatives, not monads. (Applicatives give the implementor more freedom.) 25/ 40

  35. Guideline: Postel’s law Be conservative in what you do, be liberal in what you accept from others. Conservative in what you do: use applicatives, not monads. (Applicatives give the implementor more freedom.) Liberal in what you accept: implement monads, not applicatives. (Monads give the user more power.) 25/ 40

Recommend


More recommend