1 / 53

More ML

More ML. Compiling Techniques David Walker. Today. More data structures lists More functions More modules Next week: Lexical Analysis. Lists. Lists are created with nil (makes empty list) head :: tail (makes a longer list) 5 :: nil : int list. element.

Download Presentation

More ML

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. More ML Compiling Techniques David Walker

  2. Today • More data structures • lists • More functions • More modules • Next week: Lexical Analysis

  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:1.1-2.2 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:17.1-17.9 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 Two arguments f and l fun map f l = case l of nil => [] l x :: l => (f x) :: (map f l) What does it do?

  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. 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 => ...)

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

  17. 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

  18. Anonymous functions a type definition (very convenient) 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

  19. 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 argument is pair of functions pattern match against arg result is a function!

  20. 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 ........

  21. 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

  22. 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

  23. Yet another way to create a type error fun isValue 0 = true | isValue (Bool b) = true | isValue (_) = false ex.sml:9.1-11.29 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)

  24. 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)

  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 not (fn x => x < 17) BAD!! compose (fn x => x < 17) not

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

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

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

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

  30. Parametric Polymorphism • compose not : ?? compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b) not : bool -> bool

  31. Parametric Polymorphism • compose not : ?? compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b) not : bool -> bool type of compose’s argument must equal the type of not: bool -> bool == (‘a -> ‘b)

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

  33. Parametric Polymorphism • compose not : (‘c -> bool) -> (c’ -> bool) compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b) not : bool -> bool ‘a = bool ‘b = bool

  34. Parametric Polymorphism • compose not : (‘c -> bool) -> (c’ -> bool) • (compose not) not : ?? compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b) not : bool -> 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 (fn x => x) : ? compose : (‘a -> ‘b) -> (‘c -> ‘a) -> (‘c -> ‘b)

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

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

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

  40. Parametric Polymorphism • compose (fn x => x) : ? compose : (‘d -> ‘d) -> (‘c -> ‘d) -> (‘c -> ‘d) ‘d -> ‘d (‘c -> ‘d) -> (‘c -> ‘d)

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

  42. 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: .... -> ... -> ....

  43. 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

  44. ML Modules • Signatures • Interfaces • Structures • Implementations • Functors • Parameterized structures • Functions from structures to structures

  45. 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

  46. 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))

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

  48. 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

  49. Signatures abstract type -- we don’t know the type ‘a queue 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

  50. 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 does not type check fun insert2 (q1,q2) x y : ‘a queue = (x::y::q1,q2)

More Related