a fourth look at ml

61
A Fourth Look At ML A Fourth Look At ML Chapter 11 Type-Safe Data Structures Chapter Eleven Modern Programming Languages 1

Upload: olaf

Post on 20-Jan-2016

19 views

Category:

Documents


0 download

DESCRIPTION

A Fourth Look At ML. Chapter 11 Type-Safe Data Structures. Type Definitions. Predefined, but not primitive in ML: Type constructor for lists: Defined for ML in ML. datatype bool = true | false;. datatype 'element list = nil | :: of 'element * 'element list. Outline. Enumerations - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: A Fourth Look At ML

A Fourth Look At MLA Fourth Look At MLChapter 11Type-Safe Data Structures

Chapter Eleven Modern Programming Languages 1

Page 2: A Fourth Look At ML

Type DefinitionsType DefinitionsPredefined, but not primitive in

ML:

Type constructor for lists:

Defined for ML in ML

Chapter Eleven Modern Programming Languages 2

datatype bool = true | false;

datatype 'element list = nil | :: of 'element * 'element list

Page 3: A Fourth Look At ML

OutlineOutlineEnumerationsData constructors with

parametersType constructors with

parametersRecursively defined type

constructorsFarewell to ML

◦We hardly knew ye!

Chapter Eleven Modern Programming Languages 3

Page 4: A Fourth Look At ML

Defining Your Own TypesDefining Your Own TypesNew types can be defined using

the keyword datatypeThese declarations define both:

◦type constructors for making new (possibly polymorphic) types

◦data constructors for making values of those new types

Chapter Eleven Modern Programming Languages 4

Page 5: A Fourth Look At ML

ExampleExample

day is the new type constructor and Mon, Tue, etc. are the new data constructors

Why “constructors”? In a moment we will see how both can have parameters…

Chapter Eleven Modern Programming Languages 5

- datatype day = Mon | Tue | Wed | Thu | Fri | Sat | Sun;datatype day = Fri | Mon | Sat | Sun | Thu | Tue | Wed- fun isWeekDay x = not (x = Sat orelse x = Sun);val isWeekDay = fn : day -> bool- isWeekDay Mon;val it = true : bool- isWeekDay Sat;val it = false : bool

Page 6: A Fourth Look At ML

No ParametersNo Parameters

The type constructor day takes no parameters: it is not polymorphic, there is only one day type

The data constructors Mon, Tue, etc. take no parameters: they are constant values of the day type

Capitalize the names of data constructors

Chapter Eleven Modern Programming Languages 6

- datatype day = Mon | Tue | Wed | Thu | Fri | Sat | Sun;datatype day = Fri | Mon | Sat | Sun | Thu | Tue | Wed

Page 7: A Fourth Look At ML

Strict TypingStrict Typing

ML is strict about these new types, just as you would expect

Unlike C enum, no implementation details are exposed to the programmer

Chapter Eleven Modern Programming Languages 7

- datatype flip = Heads | Tails;datatype flip = Heads | Tails- fun isHeads x = (x = Heads);val isHeads = fn : flip -> bool- isHeads Tails;val it = false : bool- isHeads Mon;Error: operator and operand don't agree [tycon mismatch] operator domain: flip operand: day

Page 8: A Fourth Look At ML

Data Constructors In Data Constructors In PatternsPatterns

You can use the data constructors in patterns

In this simple case, they are like constantsBut we will see more general cases next…

Chapter Eleven Modern Programming Languages 8

fun isWeekDay Sat = false| isWeekDay Sun = false| isWeekDay _ = true;

Page 9: A Fourth Look At ML

The The orderorder Datatype DatatypeUsed with pre-defined compare

functions◦Int.compare( )◦Real, String, Char, Time, Date, …

datatype order = LESS | GREATER | EQUAL;

- Real.compare(1.0,2.0);

val it = LESS : order- Char.compare(#"b", #"a");

val it = GREATER : order

Chapter Eleven Modern Programming Languages 9

Page 10: A Fourth Look At ML

OutlineOutlineEnumerationsData constructors with

parametersType constructors with

parametersRecursively defined type

constructorsFarewell to ML

Chapter Eleven Modern Programming Languages 10

Page 11: A Fourth Look At ML

WrappersWrappersYou can add a parameter of any type to

a data constructor, using the keyword of:datatype exint = Value of int | PlusInf | MinusInf;

In effect, such a constructor is a wrapper that contains a data item of the given type

Chapter Eleven Modern Programming Languages 11

PlusInfValue

36

MinusInf Value26

Value38

Some thingsof type exint:

Page 12: A Fourth Look At ML

Value is a data constructor that takes a parameter: the value of the int to store

It looks like a function that takes an int and returns an exint containing that int

Chapter Eleven Modern Programming Languages 12

- datatype exint = Value of int | PlusInf | MinusInf;datatype exint = MinusInf | PlusInf | Value of int- PlusInf;val it = PlusInf : exint- MinusInf;val it = MinusInf : exint- Value;val it = fn : int -> exint (* Function notation! *)- Value 3;val it = Value 3 : exint

Page 13: A Fourth Look At ML

A A ValueValue Is Not An Is Not An intint

Value 5 is an exintIt is not an int, though it contains

oneHow can we get the int out again?By pattern matching…

Chapter Eleven Modern Programming Languages 13

- val x = Value 5;val x = Value 5 : exint- x+x;Error: overloaded variable not defined at type symbol: + type: exint

Page 14: A Fourth Look At ML

Patterns With Data Patterns With Data ConstructorsConstructors

To recover a data constructor’s parameters, use pattern matching

So Value is no ordinary function: ordinary functions can't be pattern-matched this way

Chapter Eleven Modern Programming Languages 14

- val (Value y) = x;Warning: binding not exhaustive Value y = ...val y = 5 : int

Page 15: A Fourth Look At ML

An Exhaustive PatternAn Exhaustive Pattern

Like most uses of the match construct, you get a warning if it is not exhaustive

An exint can be a PlusInf, a MinusInf, or a Value

This one says what to do in all cases

Chapter Eleven Modern Programming Languages 15

- val s = case x of = PlusInf => "infinity" |= MinusInf => "-infinity" | = Value y => Int.toString y;val s = "5" : string

Page 16: A Fourth Look At ML

Pattern-Matching FunctionPattern-Matching Function

Pattern-matching function definitions are especially important when working with your own datatypes

Chapter Eleven Modern Programming Languages 16

- fun square PlusInf = PlusInf= | square MinusInf = PlusInf= | square (Value x) = Value (x*x);val square = fn : exint -> exint- square MinusInf;val it = PlusInf : exint- square (Value 3);val it = Value 9 : exint

Page 17: A Fourth Look At ML

Exception Handling (A Exception Handling (A Peek)Peek)

Patterns are also used in ML for exception handling, as in this example

Chapter Eleven Modern Programming Languages 17

- fun square PlusInf = PlusInf= | square MinusInf = PlusInf= | square (Value x) = Value (x*x)= handle Overflow => PlusInf;val square = fn : exint -> exint- square (Value 10000);val it = Value 100000000 : exint- square (Value 100000);val it = PlusInf : exint

Page 18: A Fourth Look At ML

OutlineOutlineEnumerationsData constructors with

parametersType constructors with

parametersRecursively defined type

constructorsFarewell to ML

Chapter Eleven Modern Programming Languages 18

Page 19: A Fourth Look At ML

Partial FunctionsPartial FunctionsA function that is not defined for

all values of its domain type is called a partial function

Examples:◦1/x; functions that expect a non-null

pointerIn ML, the option data type

indicates undefined valuesdatatype ‘a option = NONE |

SOME of ‘a;Chapter Eleven Modern Programming Languages 19

Page 20: A Fourth Look At ML

Type Constructors With Type Constructors With ParametersParameters

Type constructors can also use parameters: datatype 'a option = NONE | SOME of 'a;

The parameters of a type constructor are type variables, which are used in the data constructors

The result: a new polymorphic type

Chapter Eleven Modern Programming Languages 20

NONE

SOME"Hello"

Values of typestring option

SOME"world"

NONE

SOME1.5

Values of type real option

SOME123.4

Page 21: A Fourth Look At ML

Parameter Before NameParameter Before Name

Type constructor parameter comes before the type constructor name:datatype 'a option = NONE | SOME of 'a;

We have types 'a option and int option, just like 'a list and int list

Chapter Eleven Modern Programming Languages 21

- SOME 4;val it = SOME 4 : int option- SOME 1.2;val it = SOME 1.2 : real option - SOME "pig";val it = SOME "pig" : string option

Page 22: A Fourth Look At ML

Uses For Uses For optionoptionPredefined type constructor in MLUsed by predefined functions (or your

own) when the result is not always defined

Chapter Eleven Modern Programming Languages 22

- fun optdiv a b == if b = 0 then NONE else SOME (a div b);val optdiv = fn : int -> int -> int option- optdiv 7 2;val it = SOME 3 : int option- optdiv 7 0;val it = NONE : int option

Page 23: A Fourth Look At ML

Working with Working with optionoptionRetrieve the value of an option,

other than NONE, with valOfProvide a default value for NONE

with getOptval x = SOME 2 : int option

- valOf x;

val it = 2 : int

- getOpt (x,0);

val it = 2 : int

- getOpt (NONE, 0);

val it = 0 : int

See fact.smlChapter Eleven Modern Programming Languages 23

Page 24: A Fourth Look At ML

Longer Example: Longer Example: bunchbunch

An 'x bunch is either a thing of type 'x, or a list of things of type 'x

As usual, ML infers types:

Chapter Eleven Modern Programming Languages 24

datatype 'x bunch = One of 'x | Group of 'x list;

- One 1.0;val it = One 1.0 : real bunch- Group [true,false];val it = Group [true,false] : bool bunch

Page 25: A Fourth Look At ML

Example: PolymorphismExample: Polymorphism

ML can infer bunch types, but does not always have to resolve them, just as with list types

Chapter Eleven Modern Programming Languages 25

- fun size (One _) = 1= | size (Group x) = length x;val size = fn : 'a bunch -> int- size (One 1.0);val it = 1 : int- size (Group [true,false]);val it = 2 : int

Page 26: A Fourth Look At ML

Example: No PolymorphismExample: No Polymorphism

We applied the + operator (through foldr) to the list elements

So ML knows the parameter type must be int bunch

Chapter Eleven Modern Programming Languages 26

- fun sum (One x) = x= | sum (Group xlist) = foldr (op +) 0 xlist;val sum = fn : int bunch -> int- sum (One 5);val it = 5 : int- sum (Group [1,2,3]);val it = 6 : int

Page 27: A Fourth Look At ML

OutlineOutline

EnumerationsData constructors with parametersType constructors with parametersRecursively defined type

constructorsFarewell to ML

Chapter Eleven Modern Programming Languages 27

Page 28: A Fourth Look At ML

Recursively Defined Type Recursively Defined Type ConstructorsConstructorsThe type constructor being defined may

be used in its own data constructors: datatype intlist = INTNIL | INTCONS of int * intlist;

Chapter Eleven Modern Programming Languages 28

Some values oftype intlist:

INTNIL

INTCONS

the empty list

INTNIL 1

the list [1]

INTCONS INTNIL 2

INTCONS

1

the list [1,2]

Page 29: A Fourth Look At ML

Constructing Those ValuesConstructing Those Values

Chapter Eleven Modern Programming Languages 29

- INTNIL;val it = INTNIL : intlist- INTCONS (1,INTNIL);val it = INTCONS (1,INTNIL) : intlist- INTCONS (1,INTCONS(2,INTNIL));val it = INTCONS (1,INTCONS (2,INTNIL)) : intlist

INTNIL

INTCONS

the empty list

INTNIL 1

the list [1]

INTCONS INTNIL 2

INTCONS

1

the list [1,2]

Page 30: A Fourth Look At ML

An An intlistintlist Length Length FunctionFunction

A length functionMuch like you would write for native

listsExcept, of course, that native lists are

not always lists of integers…

Chapter Eleven Modern Programming Languages 30

fun intlistLength INTNIL = 0 | intlistLength (INTCONS(_,tail)) = 1 + (intListLength tail);

fun listLength nil = 0 | listLength (_::tail) = 1 + (listLength tail);

Page 31: A Fourth Look At ML

Parametric List TypeParametric List Type

A parametric list type, almost like the predefined list

ML handles type inference in the usual way:

Chapter Eleven Modern Programming Languages 31

datatype 'element mylist = NIL | CONS of 'element * 'element mylist;

- CONS(1.0, NIL);val it = CONS (1.0,NIL) : real mylist- CONS(1, CONS(2, NIL));val it = CONS (1,CONS (2,NIL)) : int mylist

Page 32: A Fourth Look At ML

Some Some mylistmylist Functions Functions

This now works almost exactly like the predefined list type constructor

Of course, to add up a list you would use foldr…

Chapter Eleven Modern Programming Languages 32

fun myListLength NIL = 0 | myListLength (CONS(_,tail)) = 1 + myListLength(tail);

fun addup NIL = 0 | addup (CONS(head,tail)) = head + addup tail;

Page 33: A Fourth Look At ML

A A foldrfoldr For For mylistmylist

Definition of a function like foldr that works on 'a mylist

Can now add up an int mylist x with: myfoldr (op +) 0 x

One remaining difference: :: is an operator and CONS is not

Chapter Eleven Modern Programming Languages 33

fun myfoldr f c NIL = c | myfoldr f c (CONS(a,b)) = f(a, myfoldr f c b);

Page 34: A Fourth Look At ML

Defining OperatorsDefining Operators

ML allows new operators to be definedLike this:

Chapter Eleven Modern Programming Languages 34

- infixr 5 CONS;infixr 5 CONS- 1 CONS 2 CONS NIL;val it = 1 CONS 2 CONS NIL : int mylist

Page 35: A Fourth Look At ML

Chinese BoxesChinese BoxesNested, square boxes

◦like Russian DollsEach box has a size (length of

side) and a color

Chapter Eleven Modern Programming Languages 35

datatype color = Red | Green | Blue;datatype 'a cbox = Contents of 'a option | Trio of int * color * 'a cbox;

Page 36: A Fourth Look At ML

Chinese Box FunctionsChinese Box FunctionsSee cbox.smlSee cbox.sml

makebox: int * color * 'a cbox -> 'a cbox

boxcount: 'a cbox -> inttracebox: 'a cbox -> unit

◦ prints the box attributes outside-inopenbox: 'a cbox -> 'a option

◦ returns the inner contentsinsert: int * color * 'a cbox -> 'a cbox

makebox2: (int * color) list * 'a option -> 'a cbox

Chapter Eleven Modern Programming Languages 36

Page 37: A Fourth Look At ML

One More FunctionOne More Functiondifflist = fn : 'a cbox -> int list

- difflist b;val it = [1,1,1,1] : int list

Chapter Eleven Modern Programming Languages 37

fun difflist1 (Trio (s, _, Trio(s2,c,box))) = (s-s2)::difflist1 (Trio(s2,c,box))| difflist1 _ = nil;

Page 38: A Fourth Look At ML

Layered Patterns with Layered Patterns with asas

Chapter Eleven Modern Programming Languages 38

fun difflist (Trio (s,_,b as Trio(s2,_,_))) = (s-s2)::difflist b| difflist _ = nil;

Page 39: A Fourth Look At ML

Polymorphic Binary TreePolymorphic Binary Treedatatype 'data tree = Empty | Node of 'data tree * 'data * 'data tree;

Chapter Eleven Modern Programming Languages 39

Some values oftype int tree:

Empty

Node

the empty tree

2

the tree 2

Empty Empty

Node 3 Empty Empty

Node 1

the tree 2

Empty Empty 2

1 3

Node

Page 40: A Fourth Look At ML

Constructing Those ValuesConstructing Those Values

Chapter Eleven Modern Programming Languages 40

- val treeEmpty = Empty;val treeEmpty = Empty : 'a tree- val tree2 = Node(Empty,2,Empty);val tree2 = Node (Empty,2,Empty) : int tree- val tree123 = Node(Node(Empty,1,Empty),= 2,= Node(Empty,3,Empty));

Page 41: A Fourth Look At ML

Increment All ElementsIncrement All Elements

Chapter Eleven Modern Programming Languages 41

fun incall Empty = Empty | incall (Node(x,y,z)) = Node(incall x, y+1, incall z);

- incall tree123;val it = Node (Node (Empty,2,Empty), 3, Node (Empty,4,Empty)) : int tree

Page 42: A Fourth Look At ML

Add Up The ElementsAdd Up The Elements

Chapter Eleven Modern Programming Languages 42

fun sumall Empty = 0 | sumall (Node(x,y,z)) = sumall x + y + sumall z;

- sumall tree123;val it = 6 : int

Page 43: A Fourth Look At ML

Convert To List Convert To List (Polymorphic)(Polymorphic)

Chapter Eleven Modern Programming Languages 43

(* In-order traversal *)

fun listall Empty = nil | listall (Node(x,y,z)) = listall x @ y :: listall z;

- listall tree123;val it = [1,2,3] : int list

Page 44: A Fourth Look At ML

Tree SearchTree Search

Chapter Eleven Modern Programming Languages 44

fun isintree x Empty = false | isintree x (Node(left,y,right)) = x=y orelse isintree x left orelse isintree x right;

- isintree 4 tree123;val it = false : bool- isintree 3 tree123;val it = true : bool

Page 45: A Fourth Look At ML

Infinite ListsInfinite Listsaka aka ““StreamsStreams””

It is possible, and often useful, to define infinite lists

The elements are computed on demand

Allows a high degree of separation between software components (functions)

Chapter Eleven Modern Programming Languages 45

Page 46: A Fourth Look At ML

The The unitunit Data Type Data TypeLike void in C++

◦a “nothing” return type, or◦an “empty” parameter list

Denoted by ( ) in ML

Chapter Eleven Modern Programming Languages 46

- print "hello\n";helloval it = () : unit- fun f () = "goodbye";val f = fn : unit -> string- f();val it = "goodbye" : string

Page 47: A Fourth Look At ML

Nodes for Infinite Linked Nodes for Infinite Linked ListsListsRecall the list type definition:

The first node slot is the dataThe second is a “pointer” to the

tailFor infinite lists, we will delay the

evaluation of the tail:

Chapter Eleven Modern Programming Languages 47

datatype 'element list = nil | :: of 'element * 'element list

datatype 'a stream = Nil | Cons of 'a * (unit -> 'a stream);

Page 48: A Fourth Look At ML

An Infinite Sequence of An Infinite Sequence of IntegersIntegers

Chapter Eleven Modern Programming Languages 48

- fun intsfrom k = Cons(k,fn()=>intsfrom(k+1));val intsfrom = fn : int -> int stream- val nums = intsfrom 5;val nums = Cons (5,fn) : int stream- val Cons(head,_) = nums;val head = 5 : int- val Cons(_,f) = nums; val f = fn : unit -> int stream- val rest = f();val rest = Cons (6,fn) : int stream- val Cons(head,_) = rest;val head = 6 : int

Page 49: A Fourth Look At ML

Head and Tail for StreamsHead and Tail for Streams

Chapter Eleven Modern Programming Languages 49

fun head Nil = raise Empty| head (Cons(h,_)) = h;

fun thunk Nil = raise Empty| thunk (Cons(_,t)) = t;

fun force f = f ();

fun tail s = force (thunk s);(* Like the real list type, just gives the next Cons *)

Page 50: A Fourth Look At ML

Traversing the StreamTraversing the Stream

Chapter Eleven Modern Programming Languages 50

- nums;val it = Cons (5,fn) : int stream- head nums;val it = 5 : int- thunk nums;val it = fn : unit -> int stream- tail nums;val it = Cons (6,fn) : int stream- val rest = tail nums;val rest = Cons (6,fn) : int stream- head rest;val it = 6 : int- tail rest;val it = Cons (7,fn) : int stream

Page 51: A Fourth Look At ML

Other Stream FunctionsOther Stream Functions

Chapter Eleven Modern Programming Languages 51

fun next Nil = raise Empty| next c = head (tail c);

fun nth 0 s = head s| nth n s = nth (n-1) (tail s);

fun filter _ Nil = Nil| filter f (Cons (h,t)) = if (f h) then Cons (h, fn () => filter f (force t)) else filter f (force t);

fun map_ _ Nil = Nil| map_ f (Cons(h,t)) = Cons(f h, fn() => map_ f (force t));

Page 52: A Fourth Look At ML

Chapter Eleven Modern Programming Languages 52

- nums;val it = Cons (5,fn) : int stream- next nums;val it = 6 : int- nth 5 nums;val it = 10 : int- val evens = filter (fn x => x mod 2 = 0) nums;val evens = Cons (6,fn) : int stream- head evens;val it = 6 : int- next evens;val it = 8 : int- val iseven = map (fn x => x mod 2 = 0) nums;val iseven = Cons (false,fn) : bool stream- nth 0 iseven;val it = false : bool- nth 1 iseven;val it = true : bool

Page 53: A Fourth Look At ML

More ExamplesMore Examples

Chapter Eleven Modern Programming Languages 53

- val takeeven = filter (fn x => x mod 2 = 0);val takeeven = fn : int stream -> int stream- val evens = takeeven (intsfrom 1);val evens = Cons (2,fn) : int stream- printStrm 10 evens;2468101214161820

Page 54: A Fourth Look At ML

A A printStrmprintStrm Function for Function for intsints

Chapter Eleven Modern Programming Languages 54

fun printStrm _ Nil = ()| printStrm 0 _ = ()| printStrm n (Cons(x,rest)) = ( print(Int.toString x ^ "\n"); printStrm (n-1) (force rest) );

val printStrm = fn : int -> int stream -> unit

Page 55: A Fourth Look At ML

Obtaining Obtaining ““AllAll”” Prime Prime NumbersNumbers

Chapter Eleven Modern Programming Languages 55

- val primes = filter isPrime (intsfrom 2);val primes = Cons (2,fn) : int stream- strm2list 1000 primes;val it = [2,3,5,7,11,13,17,19,23,29,31,37,...] : int list- nth 1000 primes;val it = 7927 : int- nth 10000 primes;val it = 104743 : int-nth 100000 primes; val it = 1299721 : int (* took 1 second *)- nth 1000000 primes;val it = 15485867 : int (* took 21 seconds *)

Page 56: A Fourth Look At ML

Implementing Implementing foldlfoldlRemember foldl f c xs =

f(xn,f(xn-1,…,f(x2,f(x1,c))…))

fun foldl _ c nil = c

| foldl f c (x::xs) = foldl f (f (x,c)) xs;

Chapter Eleven Modern Programming Languages 56

Page 57: A Fourth Look At ML

foldl for Streamsfoldl for Streams

Chapter Eleven Modern Programming Languages 57

fun foldl_ _ c Nil = Cons(c, fn()=>Nil)| foldl_ f c (Cons(a,rest)) = let val v = f (a,c) in Cons(v, fn () => foldl_ f v (force rest)) end;

Page 58: A Fourth Look At ML

More ExamplesMore ExamplesComposing Even More StreamsComposing Even More Streams

Chapter Eleven Modern Programming Languages 58

-fun sum strm = foldl_ (op +) 0 strm;val sum = fn : int stream -> int stream- val addevens = sum (takeeven (intsfrom 1));val addevens = Cons (2,fn) : int stream- printStrm 10 addevens;2612203042567290110

Page 59: A Fourth Look At ML

Yet More!Yet More!

Chapter Eleven Modern Programming Languages 59

- fun drop _ Nil = Nil| drop 0 strm = strm| drop n (Cons(x,rest)) = drop (n-1) (force rest);val drop = fn : int -> 'a stream -> 'a stream- val less5 = drop 5 nums;val less5 = Cons (10,fn) : int stream- printStrm 5 less5;1011121314val it = () : unit- fun strm2list _ Nil = nil| strm2list 0 _ = nil| strm2list n (Cons(x,rest)) = x::(strm2list (n-1) (force rest));val strm2list = fn : int -> 'a stream -> 'a list- strm2list 5 less5;val it = [10,11,12,13,14] : int list

Page 60: A Fourth Look At ML

Even More ExamplesEven More ExamplesFrom MathematicsFrom Mathematics

See:◦iterate.sml◦newton.sml◦taylor.sml

Chapter Eleven Modern Programming Languages 60

Page 61: A Fourth Look At ML

Streams in PythonStreams in PythonUses generators

◦functions that can be resumed◦thereby producing a sequence of

values

See stream.py, iterate.py, newton.py

Chapter Eleven Modern Programming Languages 61