Presentation is loading. Please wait.

Presentation is loading. Please wait.

More ML Compiling Techniques David Walker. Today More data structures lists More functions More modules.

Similar presentations


Presentation on theme: "More ML Compiling Techniques David Walker. Today More data structures lists More functions More modules."— Presentation transcript:

1 More ML Compiling Techniques David Walker

2 Today More data structures lists More functions More modules

3 Lists Lists are created with nil (makes empty list) head :: tail(makes a longer list) 5 :: nil : int list element list of elements

4 Lists Lists are created with nil (makes empty list) head :: tail(makes a longer list) 4 :: (5 :: nil) : int list element list of elements

5 Lists Lists are created with nil (makes empty list) head :: tail(makes a longer list) 3 :: 4 :: (5 :: nil) : int list element list of elements

6 Lists Lists are created with 3 :: (4 :: (5 :: nil)) : int list 3 :: 4 :: 5 :: nil : int list (true, 1) :: (false, 2) :: nil : (bool * int) list (3 :: nil) :: (2 :: nil) :: nil : (int list) list

7 Lists Lists: 3 :: [] : int list 3 :: [4, 5] : int list [true] : bool list a different way of writing nil a different way of writing a list

8 Lists Bad List: [4]::3; ???

9 Lists Bad List: [4]::3; stdIn: Error: operator and operand don't agree [literal] operator domain: int list * int list list operand: int list * int in expression: (4 :: nil) :: 3

10 Lists Bad List: [true, 5]; ???

11 Lists Bad List: [true, 5]; stdIn: Error: operator and operand don't agree [literal] operator domain: bool * bool list operand: bool * int list in expression: true :: 3 :: nil

12 List Processing Functions over lists are usually defined by pattern matching on the structure of a list Hint: often, the structure of a function is guided by the type of the argument (recall eval) fun length l = case l of nil => 0 l _ :: l => 1 + (length l)

13 List Processing fun map f l = case l of nil => [] l x :: l => (f x) :: (map f l) What does it do? Two arguments f and l

14 List Processing fun map f l = case l of nil => [] l x :: l => (f x) :: (map f l) applies the function f to every element in the list - fun add1 x = x + 1; - map add1 [1,2,3]; > val it = [2,3,4] : int list

15 List Processing fun fold f a l = case l of nil => a l x :: l => f (fold f a l) x another incredibly useful function what does it do? use it to write map.

16 ML is all about functions There are many different ways to define functions! I almost always use fun f x =... When I am only going to use a function once and it is not recursive, I write an anonymous function: (fn x =>...)

17 Anonymous functions val n = 3 val isValue = (fn t => case t of Bool _ => true | t => false) binds a variable (n) to a value (3) binds a variable (isValue) to the anonymous function value fn keyword introduces anonymous fun

18 Anonymous functions fun map f l = case l of nil => [] l x :: l => (f x) :: (map f l) fun addlist x l = map (fn y => y + x) l anonymous functions

19 Anonymous functions type ifun = int -> int val intCompose : ifun * ifun -> ifun =... fun add3 x = intCompose ((fn x => x + 2), (fn y => y + 1)) x a pair of anonymous functions a type definition (very convenient)

20 Anonymous functions type ifun = int -> int val intCompose : ifun * ifun -> ifun = fn (f,g) => (fn x => f (g x)) fun add3 x = intCompose ((fn x => x + 2), (fn y => y + 1)) x result is a function! argument is pair of functions pattern match against arg

21 Another way to write a function fun f x = can be written as: val f = (fn x =>......) provided the function is not recursive; f does not appear in

22 Another way to write a function fun f x =.... can always be written as: val rec f = (fn x =>...f can be used here...) keyword rec declares a recursive function value

23 Yet another way to write a function fun isValue Num n = true | isValue (Bool b) = true | isValue (_) = false This is just an abbreviation for fun isValue t = case t of Num n => true | Bool b => true | _ => false

24 Yet another way to create a type error fun isValue 0 = true | isValue (Bool b) = true | isValue (_) = false ex.sml: Error: parameter or result constraints of clauses don't agree [literal] this clause: term -> 'Z previous clauses: int -> 'Z in declaration: isValue = (fn 0 => true | Bool b => true | _ => false)

25 Parametric Polymorphism Functions like compose work on objects of many different types val compose = fn f => fn g => fn x => f (g x) compose (fn x => x + 1) (fn x => x + 2) compose not (fn x => x < 17)

26 Parametric Polymorphism Functions like compose work on objects of many different types val compose = fn f => fn g => fn x => f (g x) compose not (fn x => x < 17) compose (fn x => x < 17) not BAD!!

27 Parametric Polymorphism Functions like compose work on objects of many different types val compose = fn f => fn g => fn x => f (g x) compose: (a -> b) -> (c -> a) -> (c -> b) Note: type variables are written with a type variable stands for any type

28 Parametric Polymorphism Functions like compose work on objects of many different types compose: (a -> b) -> (c -> a) -> (c -> b) compose: (int -> b) -> (c -> int) -> (c -> b) can be used as if it had the type:

29 Parametric Polymorphism Functions like compose work on objects of many different types compose: (a -> b) -> (c -> a) -> (c -> b) compose: ((int * int) -> b) -> (c -> (int * int)) -> (c -> b) can be used as if it had the type:

30 Parametric Polymorphism Functions like compose work on objects of many different types compose: (a -> b) -> (c -> a) -> (c -> b) compose: (unit -> int) -> (int -> unit) -> (int -> int) can be used as if it had the type:

31 Parametric Polymorphism compose not : ?? compose : (a -> b) -> (c -> a) -> (c -> b) not : bool -> bool

32 Parametric Polymorphism compose not : ?? compose : (a -> b) -> (c -> a) -> (c -> b) not : bool -> bool type of composes argument must equal the type of not: bool -> bool == (a -> b)

33 Parametric Polymorphism compose not : ?? compose : (a -> b) -> (c -> a) -> (c -> b) not : bool -> bool a must be bool b must be bool as well (in this use of compose) therefore:

34 Parametric Polymorphism compose not : (c -> bool) -> (c -> bool) compose : (a -> b) -> (c -> a) -> (c -> b) not : bool -> bool a = bool b = bool

35 Parametric Polymorphism compose not : (c -> bool) -> (c -> bool) (compose not) not : bool -> bool compose : (a -> b) -> (c -> a) -> (c -> b) not : bool -> bool

36 Parametric Polymorphism compose not : (c -> bool) -> (c -> bool) (compose not) not : ?? compose : (a -> b) -> (c -> a) -> (c -> b) not : bool -> bool

37 Parametric Polymorphism compose (fn x => x) : ? compose : (a -> b) -> (c -> a) -> (c -> b)

38 Parametric Polymorphism compose (fn x => x) : ? compose : (a -> b) -> (c -> a) -> (c -> b) d -> d

39 Parametric Polymorphism compose (fn x => x) : ? compose : (a -> b) -> (c -> a) -> (c -> b) d -> d must be the same ie: a = d b = d

40 Parametric Polymorphism compose (fn x => x) : ? compose : (d -> d) -> (c -> d) -> (c -> d) d -> d must be the same ie: a = d b = d

41 Parametric Polymorphism compose (fn x => x) : ? compose : (d -> d) -> (c -> d) -> (c -> d) d -> d (c -> d) -> (c -> d)

42 What is the type of map? fun map f l = case l of nil => [] l x :: l => (f x) :: (map f l)

43 What is the type of map? fun map f l = case l of nil => [] l x :: l => (f x) :: (map f l) Hint: top-level shape is:.... ->... ->....

44 What is the type of map? fun map f l = case l of nil => [] l x :: l => (f x) :: (map f l) Solution: ( a -> b) -> a list -> b list

45 ML Modules Signatures Interfaces Structures Implementations Functors Parameterized structures Functions from structures to structures

46 Structures structure Queue = struct type a queue = a list * a list exception Empty val empty = (nil, nil) fun insert (x, q) = … fun remove q = … end

47 Structures structure Queue = struct type a queue = a list * a list exception Empty... end fun insert2 q x y = Queue.insert (y, Queue.insert (q, x))

48 Structures structure Queue = struct... end structure Q = Queue fun insert2 q x y = Q.insert (y, Q.insert (q, x)) convenient abbreviation

49 Structures structure Queue = struct type a queue = a list * a list... end fun insert2 (q1,q2) x y : a queue = (x::y::q1,q2) by default, all components of the structure may be used -- we know the type a queue

50 Signatures signature QUEUE = sig type a queue exception Empty val empty : a queue val insert : a * a queue -> a queue val remove : a queue -> a * a queue end abstract type -- we don t know the type a queue

51 Information hiding signature QUEUE = sig type a queue... end structure Queue :> QUEUE = struct type a queue = a list * a list val empty = (nil, nil) … end fun insert2 (q1,q2) x y : a queue = (x::y::q1,q2) does not type check

52 Signature Ascription Opaque ascription Provides abstract types structure Queue :> QUEUE = … Transparent ascription A special case of opaque ascription Hides fields but does not make types abstract structure Queue_E : QUEUE = … SEE Harper, chapters for more on modules

53 Other things functors (functions from structures to structures) references (mutable data structures) ref e; !e; e1 := e2 while loops, for loops arrays (* comments (* can be *) nested *) a bunch of other stuff...

54 Last Things Learning to program in SML can be tricky at first But once you get used to it, you will never want to go back to imperative languages Check out the reference materials listed on the course homepage


Download ppt "More ML Compiling Techniques David Walker. Today More data structures lists More functions More modules."

Similar presentations


Ads by Google