tim sheard oregon graduate institute lecture 6: monads and interpreters cse 510 section fsc winter...

40
Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC CSE 510 Section FSC Winter 2004 Winter 2004

Post on 20-Dec-2015

219 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

Tim SheardOregon Graduate Institute

Lecture 6: Monads and Interpreters

CSE 510 Section FSCCSE 510 Section FSC

Winter 2004Winter 2004

Page 2: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

2Cs510 FSC Winter 2005

Interpreters are hard to modify

Consider the interpreters for Exp and ComConsider 3 extensions Adding a print command Adding a divide expression and catching

divide by 0 errors Adding a notion of multiple results

Drastic changes need to be made to the structure of the interpreter.

Page 3: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

3Cs510 FSC Winter 2005

Extended Abstract Syntaxdatatype Exp =

Constant of int (* 5 *)

| Variable of string (* x *)

| Minus of (Exp * Exp) (* x - 5 *)

| Greater of (Exp * Exp) (* x > 1 *)

| Times of (Exp * Exp) (* x * 4 *)

| Divide of (Exp * Exp) (* x / 3 *)

datatype Com =

Assign of (string * Exp) (* x := 1 *)

| Seq of (Com * Com) (* { x := 1; y := 2 } *)

| If of (Exp * Com * Com) (* if x then x := 1 else y := 1 *)

| While of (Exp * Com) (* while x>0 do x := x - 1 *)| Declare of (string * Exp * Com) (* Declare x = 1 in x := x - 1 *)

| Print of string * Exp (* Print "answer" (x+2) *)

Page 4: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

4Cs510 FSC Winter 2005

Adding a Print command

New types type env = (string * int) list eval0 : Exp -> env -> int interp1 : Com -> env -> (env * string)

The type of Eval doesn’t change since evaluation of Exp can’t cause any printing.A Com is an env transformer and an output producer.

String produced by printing

Page 5: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

5Cs510 FSC Winter 2005

New interp functionfun interp1 stmt env =case stmt of Assign(name,e) => let val v = eval0 e env in (set name v env,"") end | Seq(x1,x2) => let val (env1,s1) = interp1 x1 env val (env2,s2) = interp1 x2 env1 in (env2,s1 ^ s2) end | If(e,s1,s2) => let val x = eval0 e env in if x=1

then interp1 s1 env else interp1 s2 env

end

Assignment cause no output

Collect output from both sub-commands

Page 6: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

6Cs510 FSC Winter 2005

Interp continued| While(e,body) =>

let fun loop env s =

let val v = eval0 e env

in if v=0

then (env,s) else let val (env1,s1) = interp1 body env

in loop env1 (s^s1) end

end

in loop env "" end

| Declare(nm,e,stmt) =>

let val v = eval0 e env

val env1 = ext nm v env

val (env2,s) = interp1 stmt env1

in (remove env2,s) end;

Output collected from many

traversals of loop

Env is shrunk but output is propagated

Page 7: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

7Cs510 FSC Winter 2005

Add Divide and error catching

New types eval2 : Exp -> env -> int option interp2 : Com -> env -> env option

WhereDatatype ‘a option = NONE | SOME of ‘a

Page 8: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

8Cs510 FSC Winter 2005

Eval2fun eval2 exp env = case exp of Constant n => SOME n| Variable s => SOME (lookup s env)| Minus(x,y) => (case eval2 x env of SOME a => (case eval2 y env of SOME b => SOME(a - b) | _ => NONE) | _ => NONE) | . . . (* similar for Greter and Times *)| Divide(x,y) => (case eval2 x env of SOME a => (case eval2 y env of SOME 0 => NONE | SOME b => SOME(a div b) | _ => NONE) | _ => NONE)

Error production

Error propagation

Page 9: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

9Cs510 FSC Winter 2005

interp2fun interp2 stmt env =case stmt of Assign(name,e) => (case eval2 e env of SOME v => SOME(set name v env) | _ => NONE)| Seq(s1,s2) => (case interp2 s1 env of SOME env1 => interp2 s2 env1 | NONE => NONE)| If(e,s1,s2) => (case eval2 e env of SOME x => if x=1

then interp2 s1 env else interp2 s2 env

| NONE => NONE)| . . . (* similar for While etc. *)

Page 10: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

10Cs510 FSC Winter 2005

Additions for multiple values

E.g. Suppose x [9,5] y [2,4]Then (x – y) [7,5,3,1] [9-2, 9-4, 5-2, 5-4]

New types type env = (string * int list) list; eval3 : Exp -> env -> int list Interp3 : Com -> env -> env

Useful function – combines map and append

fun mapp f [] = [] | mapp f (x::xs) = (f x) @ (mapp f xs);Appends results rather

than consing them

Page 11: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

11Cs510 FSC Winter 2005

Eval3fun eval3 exp env = case exp of Constant n => [n]| Variable s => lookup s env| Minus(x,y) => let val xs = eval3 x env fun f x = let val ys = eval3 y env fun g y = [x - y] in mapp g ys end in mapp f xs end| Greater(x,y) => let val xs = eval3 x env fun f x = let val ys = eval3 y env fun g y = [ if x '>' y then 1 else 0] in mapp g ys end in mapp f xs end| . . .

Constants have singleton values

Recursive calls give multiple results which

are then combined

Page 12: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

12Cs510 FSC Winter 2005

Example run

val env3 = [("x",[9,5]),("y",[2,4])]

val test2 = eval3

(Minus (Variable "x",Variable "y")) env3;

-| test2;

val it = [7,5,3,1] : int list

Page 13: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

13Cs510 FSC Winter 2005

Notes

Each new addition made drastic changes to the structure of the code. Print – extra results returned in pair Divide – case analysis to determine if

SOME or NONE Mulitiple Answers – results are lists,

need complicated use of mapp to combine results

Consider making an interpreter with all three changes

Page 14: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

14Cs510 FSC Winter 2005

Patterns

(x,””) SOME x [x]

Let val (a,s) = e1

val (b,t) = e2

In f[s^t]

Case e of

SOME z => m

NONE => NONE

Let val xs = e

fun f x = …

In mapp f xs end

These patterns can be captured by two functions

Return : ‘a -> ‘a M

Bind : ‘a M -> (‘a -> ‘b M) -> ‘b M

Where M is some type constructor. This pattern is called a Monad

‘a M = (‘a * string) ‘a M = ‘a option ‘a M = ‘a list

Page 15: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

15Cs510 FSC Winter 2005

Output monad

fun return x = (x,"");

fun bind (x,s1) g =

let val (y,s2) = g x in (y,s1^s2) end;

Page 16: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

16Cs510 FSC Winter 2005

Error Monaddatatype ‘a option = NONE | SOME of

fun return x = SOME x;

fun bind (SOME x) g = g x

| bind NONE g = NONE;

Page 17: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

17Cs510 FSC Winter 2005

Monad of Multiple results

datatype ‘a list = [] | ‘a :: ‘a list;

fun return x = [x];

fun bind xs g = mapp g xs;

Page 18: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

18Cs510 FSC Winter 2005

Monads in Meta MLMonads are built into MetaMLUsers can define their own MonadsMonads support their own special syntax Do m { x <- e; y } === bind e (fn x=> y) Return m x === return x

Monads require extensions to ML Higher order type constructors

Type constructors (I.e. things like list) which take type constructors as arguments

Polymorphic components to records

Page 19: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

19Cs510 FSC Winter 2005

Higher Order Type Constructors

datatype ('a,'T : * -> * ) tree =

Tip of 'a

| Node of (('a,'T)tree) 'T;

datatype 'a binary = bin of 'a * 'a;

val z: (int,list) tree =

Node [ Tip 4, Tip 2 ];

val w: (int,binary ) tree =

Node(bin (Tip 1,Node(bin (Tip 3, Tip 0))));

Page 20: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

20Cs510 FSC Winter 2005

Polymorphic Componentsdatatype a = A of (['a].'a list -> 'a list);

fun copy [] = []

| copy (x::xs) = x :: (copy xs);

val a1 = A(rev);

val a2 = A copy;

-| fun f x y (A g) = (g x, g y);

val f = Fn : ['a,'b].'b list -> 'a list -> a

-> ('b list * 'a list )

-| val q = f [1,2,3] ["x","y","d"] a1;

val q = ([3,2,1],["d","y","x"]) :

(int list * string list )

Page 21: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

21Cs510 FSC Winter 2005

List Monoid example

datatype list_monoid = LM of

{ inject : ['a].'a -> 'a list,

plus : ['a]. 'a list -> 'a list -> 'a list,

zero : ['a].'a list

};

val lm1 = LM{inject = fn x => [x],

plus = fn x => fn y => x@y,

zero = []}

Page 22: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

22Cs510 FSC Winter 2005

Pattern Matching to accessfun f (LM{inject=inj, plus = sum, zero = z}) =

(sum z (inj 2), sum (inj true) (inj false));

-| f lm1;

val it = ([2],[true ,false ]) :

(int list * bool list )

Page 23: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

23Cs510 FSC Winter 2005

MonadsA Monad is A type constructor T

a type to type function and 2 polymorphic functions

unit : ‘a -> ‘a T bind: (‘a T) -> (‘a -> ‘b T) -> (‘b T)

an expression with type ‘a T is a computation returns a value of type ‘a might perform a T action

Print, propogate errors, return multiple results

Page 24: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

24Cs510 FSC Winter 2005

Instances of Monad Actions

Performing input/outputChanging the value of a mutable variableRaising an exception

Monads can be “emulated” with pure functional programs by threading stores, or I/O streams, or

exception continuations in and out of all computations

Page 25: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

25Cs510 FSC Winter 2005

The standard morphisms

Return : creates a simple (nullary) action which does nothingBind: sequences two actions

Non-standard morphisms describe the actions of the monad

Page 26: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

26Cs510 FSC Winter 2005

Monads in MetaMLUses both HHTC and local polymorphism

datatype ('m : * -> * ) monad =

Mon of

(['a]. 'a -> 'a 'm) *

(['a,'b]. ('a 'm) -> ('a -> 'b 'm) -> 'b 'm);

type 'x Id = 'x;

val Id = (Mon (fn x => x, fn x => fn f => f x))

: Id Monad;

Page 27: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

27Cs510 FSC Winter 2005

Do and ReturnMetaML’s interface to the standard morphisms unit and bind

val ex =

let fun bind (SOME x) f = f x

| bind NONE f = NONE

in (Mon(SOME,bind)) : option Monad end;

fun option f x =

Do ex

{ z <- x

; Return ex (f z)

};

vs

fun option f x = bind x (fn z => unit (f z));

Page 28: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

28Cs510 FSC Winter 2005

Syntactic SugarDo (Mon(unit,bind)) { x <- e; f }

= bind e (fn x => f)

Return (Mon(unit,bind)) e = unit e

Do m { x1 <- e1; x2 <- e2 ; x3 <- e3 ; e4 } =

Do m { x1 <- e1; Do m { x2 <- e2 ; Do m { x3 <- e3 ; e4 }}}

Page 29: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

29Cs510 FSC Winter 2005

Output Monad again

datatype 'a OP = OP of 'a * string;

fun return x = OP(x,"");

fun bind (OP(x,s1)) g =

let val OP(y,s2) = g x

in OP(y,s1^s2) end;

val om = Mon(return,bind);

Page 30: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

30Cs510 FSC Winter 2005

Error (option) Monad again

val em = let fun return x = SOME x;

fun bind (SOME x) g = g x

| bind NONE g = NONE;

in Mon(return,bind) end;

Page 31: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

31Cs510 FSC Winter 2005

Multiple values (list) Monad again

val mvm =

let fun return x = [x];

fun mapp f [] = []

| mapp f (x::xs) = (f x) @ (mapp f xs);

fun bind xs g = mapp g xs;

in Mon(return,bind) end;

Page 32: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

32Cs510 FSC Winter 2005

The interpreter one more time

(* eval4: ‘m Monad -> Exp -> (string * int ‘m ) list -> int ‘m *)

fun eval4 m exp env = case exp of Constant n => Return m n| Variable s => lookup s env| Minus(x,y) => Do m { a <- eval4 m x env ; b <- eval4 m y env ; Return m (a - b) }| Greater(x,y) => Do m { a <- eval4 m x env ; b <- eval4 m y env ; Return m (if a '>' b then 1 else 0) }| Times(x,y) => Do m { a <- eval4 m x env ; b <- eval4 m y env ; Return m (a * b) }

Page 33: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

33Cs510 FSC Winter 2005

Examplesval term =

(Minus (Variable "x",Variable "y"))

val envMVM = [("x",[9,5]),("y",[2,4])]

val ans1 = eval4 mvm term envMVM;

val it = [7,5,3,1] : int list

val envEM = [("x",SOME 4),("y",SOME 2)]

val ans2 = eval4 em term envEM;

val it = SOME 2 : int option

Page 34: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

34Cs510 FSC Winter 2005

Interp, one more timefun interp4 m stmt env =

case stmt of

Assign(name,e) => Do m { v <- eval4 m e env

; Return m(set name (Return m v) env) }

| Seq(s1,s2) => Do m { env1 <- interp4 m s1 env

; interp4 m s2 env1 }

| If(e,s1,s2) =>

Do m { x <- eval4 m e env

; if x=1 then interp4 m s1 env else interp4 m s2 env }

| While(e,body) =>

let fun loop env =

Do m { v <- eval4 m e env

; if v=0

then Return m env

else Do m { env1 <- interp4 m body env; loop env1 }}

in loop env end

| Declare(nm,e,stmt) =>

Do m { v <- eval4 m e env

; env2 <- interp4 m stmt (ext nm (Return m v) env)

; Return m (remove env2) } ;

Page 35: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

35Cs510 FSC Winter 2005

All features at once

Now making an interpreter with all the features is easyDefine a new monad with all the featuresAdd a few new cases for Print and DivideWrite a few non-standard morphisms Inject some new output for print Raise an error for divide by zero

Page 36: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

36Cs510 FSC Winter 2005

New Monaddatatype 'a M = M of (('a list) option) * string;

fun return x = M(SOME[x],"");fun mapp f [] = M(SOME[],"") | mapp f (x::xs) = (case f x of M(NONE,s) => M(NONE,s) | M(SOME ys,s1) => (case mapp f xs of M(SOME zs,s2) => M(SOME(ys @ zs),s1^s2) | M(NONE,s2) => M(NONE,s1^s2))) fun bind (M(NONE,s)) g = M(NONE,s) | bind (M(SOME xs,s1)) g = let val M(zs,s2) = mapp g xs in M(zs,s1^s2) end

val m = Mon(return,bind);

Page 37: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

37Cs510 FSC Winter 2005

Non-Standard morphisms

fun output s = M(SOME[s],s);

fun fail s = M(NONE,s);

Page 38: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

38Cs510 FSC Winter 2005

Ultimate interpreter(* eval5 : Exp -> (string * int M) list -> int M *)fun eval5 exp env = case exp of Constant n => Return m n| Variable s => lookup s env| Minus(x,y) => Do m { a <- eval5 x env ; b <- eval5 y env ; Return m (a - b) }| Greater(x,y) => Do m { a <- eval5 x env ; b <- eval5 y env ; Return m (if a '>' b then 1 else 0)}| Times(x,y) => Do m { a <- eval5 x env ; b <- eval5 y env ; Return m (a * b) }| Divide(x,y) => Do m { a <- eval5 x env ; b <- eval5 y env ; if b = 0 then fail "Divide by 0" else Return m (a div b) }

Page 39: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

39Cs510 FSC Winter 2005

interp5(* interp5 : Com -> (string * int M) list -> (string * int M) list M *)

fun interp5 stmt env =case stmt of Assign(name,e) => Do m { v <- eval5 e env; Return m(set name (Return m v) env) }| Seq(s1,s2) => Do m { env1 <- interp5 s1 env; interp5 s2 env1 }| If(e,s1,s2) => Do m { x <- eval5 e env ; if x=1 then interp5 s1 env else interp5 s2 env }| While(e,body) => let fun loop env = Do m { v <- eval5 e env ; if v=0 then Return m env else Do m { env1 <- interp5 body env ; loop env1 }} in loop env end

Page 40: Tim Sheard Oregon Graduate Institute Lecture 6: Monads and Interpreters CSE 510 Section FSC Winter 2004 Winter 2004

40Cs510 FSC Winter 2005

Interp5 continued(* interp5 : Com -> (string * int M) list -> (string * int M)

list M *)

fun interp5 stmt env =

case stmt of

. . .

| Declare(nm,e,stmt) =>

Do m { v <- eval5 e env

; env2 <- interp5 stmt (ext nm (Return m v) env)

; Return m (remove env2) }

| Print(s,e) =>

Do m { v <- eval5 e env

; output (s^" "^(show v))

; Return m env }