Download presentation

Presentation is loading. Please wait.

Published byJairo Chatwin Modified over 2 years ago

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

Similar presentations

© 2017 SlidePlayer.com Inc.

All rights reserved.

Ads by Google