1 / 71

A Fourth Look At ML

A Fourth Look At ML. Additional information Programming in ML A Gentle Introduction to ML Source level debugging in Poly/ML. Download as Power Point file for saving or printing . Type Definitions. Predefined, but not primitive in ML: Type constructor for lists: Defined for ML in ML.

sigmund
Download Presentation

A Fourth Look At 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. A Fourth Look At ML • Additional information • Programming in ML • A Gentle Introduction to ML • Source level debugging in Poly/ML Download as Power Point file for saving or printing. Modern Programming Languages - Chapter 11

  2. 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 Modern Programming Languages - Chapter 11

  3. Outline • Enumerations • Data constructors with parameters • Type constructors with parameters • Recursively defined type constructors • Farewell to ML – For a little while Modern Programming Languages - Chapter 11

  4. Programmer Defined Types • New types can be defined using the keyword datatype • These declarations define both: • type constructors for making new (possibly polymorphic) types • data constructors for making values of those new types Modern Programming Languages - Chapter 11

  5. Example datatype day = Mon | Tue | Wed | Thu | Fri | Sat | Sun;datatype day = Fri | Mon | Sat | Sun | Thu | Tue | Wedfun isWeekDay x = not (x = Sat orelse x = Sun);val isWeekDay = fn : day -> boolisWeekDay Mon;val it = true : boolisWeekDay Sat;val it = false : bool • 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… Modern Programming Languages - Chapter 11

  6. No Parameters datatype day = Mon | Tue | Wed | Thu | Fri | Sat | Sun;datatype day = Fri | Mon | Sat | Sun | Thu | Tue | Wed • The type constructorday takes no parameters: it is not polymorphic, there is only one day type • The data constructorsMon, Tue, etc. take no parameters: they are constant values of the day type • Convention is to capitalize the names of data constructors Modern Programming Languages - Chapter 11

  7. Strict Typing datatype flip = Heads | Tails;datatype flip = Heads | Tailsfun isHeads x = (x = Heads);val isHeads = fn : flip -> boolisHeads Tails; val it = false : boolisHeads Mon;Error: Can't unify flip with day (Different type constructors) Found near isHeads(Mon) operator domain: flip operand: day • ML strictly enforces operations on new types • Unlike C enum, no implementation details are exposed to the programmer. The following defines C type flip with Heads=0, Tails=1. enum flip {Heads, Tails}; Modern Programming Languages - Chapter 11

  8. Data Constructors In Patterns fun isWeekDay Sat = false| isWeekDay Sun = false| isWeekDay _ = true; • Data constructors can be used in patterns • In this simple case, similar to constants • More general case where constructor contains a typed data item, considered next Modern Programming Languages - Chapter 11

  9. Outline • Enumerations • Data constructors with parameters • Type constructors with parameters • Recursively defined type constructors • Farewell to ML Modern Programming Languages - Chapter 11

  10. Datatype Parameters - Wrappers • Parameterize any type to a data constructor, using the keyword of:datatype IR = I of int | R of real; • In effect, such a constructor is a wrapper that contains a data item of the given type Modern Programming Languages - Chapter 11

  11. Datatype Parameters - Wrappers datatype IR = I of int | R of real; I R b a 38.5 4 val a = R 38.5;val a = R 38.5 : IR R; val it = fn:real->IR R 5; error val b = I 4;val b = I 4 : IR I; val it = fn:int->IR I 3.14; error Modern Programming Languages - Chapter 11

  12. Wrappers • You 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 w Value x PlusInf r Value 38 36 Some things of type exint: MinusInf Value 26 q s Modern Programming Languages - Chapter 11

  13. Wrapper Example datatype exint = Value of int | PlusInf | MinusInf; datatype exint = MinusInf | PlusInf | Value of int val s = MinusInf;val s = MinusInf : exintValue; function signatureval it = fn : int -> exintval r = Value 38;val r = Value 38 : exint • Value is a data constructor that takes a parameter: the value of the int to store • Signature is a function that takes an int and returns an exint containing that int s MinusInf Value r 38 Modern Programming Languages - Chapter 11

  14. A Value Is extint Not int val x = Value 5;val x = Value 5 : exint x+x;Error: overloaded variable not defined at type symbol: + type: exint (Value 5) + (Value 5); Error: overloaded variable not defined at type symbol: + type: exint Value x 5 • Value 5 is an exint • It is not an int, though it contains one • The int accessed by pattern matching Modern Programming Languages - Chapter 11

  15. Patterns With Data Constructors val x = Value 5; val x = Value 5 : exint val (Value y) = Value 5; val y = 5 : int Value x 5 • 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 y 5 Modern Programming Languages - Chapter 11

  16. Exhaustive Patterns val x = Value 5;val s = case x of PlusInf => "infinity" |MinusInf => "-infinity" | Value y => Int.toString y;val s = "5" : string An exint can be a PlusInf, a MinusInf, or a Value val x = Value 5;val s = case x of PlusInf => 9999999999999999 | MinusInf => ~9999999999999999 | Value y => y; val s = 5 : int Modern Programming Languages - Chapter 11

  17. Pattern-Matching Function fun square PlusInf = PlusInf| square MinusInf = PlusInf| square (Value x) = Value (x*x);val square = fn : exint -> exintsquare MinusInf;val it = PlusInf : exintsquare (Value 3);val it = Value 9 : exint Pattern-matching function definitions are especially important with programmer defined datatypes Modern Programming Languages - Chapter 11

  18. Example - extint Factorial fun mult (Value x) (Value y) = Value (x*y);val mult = fn : exint -> exint -> exint mult (Value 5) (Value 4);val it = Value 20 : exint fun fact PlusInf = PlusInf | fact MinusInf = MinusInf| fact (Value 0) = Value 1| fact (Value n) = mult (fact (Value(n-1))) (Value n);val fact = fn : exint -> exint fact (Value 5);val it = Value 120 : exint Modern Programming Languages - Chapter 11

  19. Exercise 1 • Give a datatype declaration for type constructor color with data constructor red, green, yellow, blue, white. • Define function primary that returns true when the single parameter is red, green or blue; else return false. • Give a parameterized datatype declaration for type number of integer (anInt) or real (aReal). datatype exint = Value of int | PlusInf | MinusInf; val x = aReal 5.0; val x = aReal 5.0 : number val y = anInt 4; val y = anInt 4 : number Modern Programming Languages - Chapter 11

  20. Exercise 1 Continued • Define the function plus of type: number->number->number that adds two numbers, when adding anInt and aReal return aReal. Coerce int to real:real(3) converts int type to real. val x = aReal 5.0; val y = anInt 4; plus x y; val it = aReal 9.0 : number plus y y; val it = anInt 8 : number Modern Programming Languages - Chapter 11

  21. Outline • Enumerations • Data constructors with parameters • Type constructors with parameters • Recursively defined type constructors • Farewell to ML Modern Programming Languages - Chapter 11

  22. Type Constructors With Parameters • Type constructors without parameters: datatype EXINT = NOINT | SOMEINT of int; • Type constructors with parameters: datatype 'a option = NONE | SOME of 'a; • 'a the type parameter; option the datatype name • Type constructor parameters are type variables • Result: a new polymorphic type bound at execution time Modern Programming Languages - Chapter 11

  23. Type Constructors With Parameters • Type constructors without parameters:datatype EXINT = NOINT | SOMEINT of int;NOINT; val it = NOINT : EXINTSOMEINT 12; val it = SOMEINT 12 : EXINT • Type constructors with parameters: datatype 'a option = NONE | SOME of 'a; NONE; val it = NONE : ‘a optionSOME 45; val it = SOME 45 : int option SOMEINT SOME 45 1 SOME NONE SOMEINT NOINT "world" 123 Values of type string option andint option Values of type EXINT Modern Programming Languages - Chapter 11

  24. Parameter Before Name SOME;val it = fn : 'a -> 'a option SOME 4;val it = SOME 4 : int optionSOME 1.2;val it = SOME 1.2 : real option SOME "pig";val it = SOME "pig" : string option SOME [1,2,3]; val it = SOME [1, 2, 3] : int list option • Type constructor parameter 'a before constructor name:datatype 'a option = NONE | SOME of 'a; • Types 'a option and int option, just like 'a list and int list. Modern Programming Languages - Chapter 11

  25. Uses of our option datatype • Predefined type constructor in ML • Used by predefined functions (or your own) when the result is not always defined fun optdiv a b =if b = 0 then NONE else SOME (a div b);val optdiv = fn : int -> int -> int optionoptdiv 7 2;val it = SOME 3 : int optionoptdiv 7 0;val it = NONE : int option Modern Programming Languages - Chapter 11

  26. Uses of option datatype datatype 'a option = NONE | SOME of 'a; datatype exint = Value of int | PlusInf | MinusInf; val x = SOME (Value 3); val x = SOME (Value 3) : exint option SOME (SOME 5); val it = SOME (SOME 5) : int option option SOME (SOME 5, 3.14); val it = SOME (SOME 5, 3.14) : (int option * real) option Modern Programming Languages - Chapter 11

  27. Longer Example: bunch datatype 'x bunch = One of 'x | Group of 'x list; • An 'x bunch is either one of type 'x, or a list of type 'x • As usual, ML infers types: One 1.0;val it = One 1.0 : real bunchGroup [true,false];val it = Group [true,false] : bool bunch Modern Programming Languages - Chapter 11

  28. Example: Polymorphism datatype 'x bunch = One of 'x | Group of 'x list; fun size (One _) = 1| size (Group x) = length x;val size = fn : 'a bunch -> intsize (One 1.0);val it = 1 : intsize (Group [true, false]);val it = 2 : int • ML can infer bunch types, but does not always have to resolve them, just as with list types Modern Programming Languages - Chapter 11

  29. Example: No Polymorphism datatype 'x bunch = One of 'x | Group of 'x list;fun sum (One x) = x| sum (Group []) = 0| sum (Group (h::t)) = h + sum (Group t);val sum = fn : int bunch -> intsum (One 5);val it = 5 : intsum (Group [1,2,3]);val it = 6 : int • Applied the + operator to the list elements • ML determines int bunch the parameter type Modern Programming Languages - Chapter 11

  30. Exercise 2Which are valid? datatype bunch = One of int | Group of int list; • One 3; • One "Hi"; • Group [1,2,3]; • Group ["Hi", "OK"]; datatype 'x bunch = One of 'x | Group of 'x list; • One 3; • One "Hi"; • Group [1,2,3]; • Group ["Hi", 3]; • Group [One 1, One 2]; • Group [One "Hi", One 3]; • Group [Group [1,2], Group[3,4]]; • Group [Group ["Hi", "OK"], Group[1,2]]; Modern Programming Languages - Chapter 11

  31. Fix the error. Exercise 2 datatype intbunch = One of int | Group of int list; fun sum (One i) = i | sum (Group []) = 0 | sum (Group (h::t))=(sum h)+(sum(Group t)); Are these valid? the same? datatype intbunch = One of int | Group of int list; Group[1,2,3]; datatype intbunch = One of int | Group of intbunch list; Group[One 1, One 2, One 3]; Group[One 1, Group[One 2, One 3]]; Modern Programming Languages - Chapter 11

  32. Exercise 2 datatype intnest = INT of int | LIST of intnest list; fun intret (INT i) = i| intret (LIST [a]) = intret a | intret (LIST (h::t)) = intret (LIST t);intret (INT 9); returns 9 intret (LIST [INT 4, INT 3]); returns 3 9 INT INT INT LIST 4 3 Write function sum of type intnest that sums all integers in an intnest. sum (LIST [ INT 5, INT 4 ]); returns 9 Hint: match (INT x) and (LIST L). For (LIST L), L is a list with hd L an INT and tl L a LIST. Return 0 when L is null, otherwise sum the INT and LIST parts. Modern Programming Languages - Chapter 11

  33. Outline • Enumerations • Data constructors with parameters • Type constructors with parameters • Recursively defined type constructors • Farewell to ML Modern Programming Languages - Chapter 11

  34. Recursively Defined Type Constructors The type constructor being defined may be used in its own data constructors:datatype intlist = INTNIL | INTCONS of int * intlist; val x = INTNIL; Some values of type intlist: INTCONS(1,INTNIL) INTCONS(1, INTCONS(2,INTNIL)) Modern Programming Languages - Chapter 11

  35. Construction as a Tuple datatype intlist = INTNIL | INTCONS of int * intlist; INTNIL;val it = INTNIL : intlistINTCONS (1,INTNIL);val it = INTCONS (1,INTNIL) : intlistINTCONS (1,INTCONS(2,INTNIL)); val x = INTNIL; INTCONS(1,INTNIL) INTCONS(1, INTCONS(2,INTNIL)) Modern Programming Languages - Chapter 11

  36. An intlist Length Function datatype intlist = INTNIL | INTCONS of int * intlist; fun intListLength INTNIL = 0| intListLength (INTCONS(_,tail)) = 1 + (intListLength tail); val x = INTCONS (3, INTCONS (4, INTNIL)); intListLength x; val it = 2 : int intlist similar to predefined lists except use of INTNIL or int * intlist tuples for each element Modern Programming Languages - Chapter 11

  37. Exercise 2.5 datatype intlist = INTNIL | INTCONS of int * intlist; fun intlistLength INTNIL = 0| intlistLength (INTCONS(_,tail)) = 1 + (intlistLength tail); Integer list sum function. fun sum [] = 0| sum (h::t) = h + sum t; Give the function to sum an intlist. sum (INTCONS (3, INTCONS (4, INTNIL))); return 7 Modern Programming Languages - Chapter 11

  38. Parametric List Type datatype 'element mylist = NIL | CONS of 'element * 'element mylist; • A parametric list type using nested tuples, similar to predefined list • 'element is polymorphic type parameter • Allows a mylist datatype of polymorphic types CONS(1.0, NIL);val it = CONS (1.0,NIL) : real mylistCONS(1, CONS(2, NIL));val it = CONS (1,CONS (2,NIL)) : int mylist Modern Programming Languages - Chapter 11

  39. list and mylist Functions datatype 'element mylist = NIL | CONS of 'element * 'element mylist; • Similar to predefined list type constructor fun length [] = 0 | length (_::t) = 1 + length t; length [5,2,3,6]; return 4 fun myLength NIL = 0| myLength (CONS(_,t)) = 1 + myLength t;myLength (CONS(1, CONS(2, NIL))); return 2 Modern Programming Languages - Chapter 11

  40. list and mylist Functions datatype 'element mylist = NIL | CONS of 'element * 'element mylist; Of course, to add up a list could use foldr… fun addup [] = 0| addup (h::t) = h + addup t;addup [1,2]; return 3 fun myAddup NIL = 0| myAddup (CONS(h,t)) = h + myAddup t;myAddup (CONS(1, CONS(2, NIL))); returns 3 Modern Programming Languages - Chapter 11

  41. A foldr for mylist fun myfoldr f c NIL = c | myfoldr f c (CONS(a,b))=f(a,myfoldr f c b);myfoldr (op +) 0 (CONS (1, CONS(2, NIL))); 3 • myfoldr works on 'a mylist • One difference: :: is an operator and CONS is not fun foldr f c [] = c | foldr f c (a::b) = f(a, foldr f c b); foldr (op +) 0 [1,2]; 3 Modern Programming Languages - Chapter 11

  42. Exercise 3 fun map _ [] = [] | map f (h::t) = (f h)::(map f t);map (fn x => x + 1) [1,2,3];val it = [2, 3, 4] : int list • Write mymap function for a mylist. datatype 'el mylist = NIL | CONS of 'el * 'el mylist; val c = CONS(1,CONS(2,CONS(3, NIL))); val c=CONS(1,CONS(2,CONS(3,NIL))):int mylist mymap (fn x => x + 1) c; val it = CONS(2,CONS(3,CONS(4,NIL))):int mylist Modern Programming Languages - Chapter 11

  43. Exercise 3 datatype 'el mylist = NIL | CONS of 'el * 'el mylist; val c = CONS(1,CONS(2,CONS(3, NIL))); val c=CONS(1,CONS(2,CONS(3,NIL))):int mylist fun snoc a NIL = CONS(a,NIL) | snoc a (CONS(h,t)) = CONS(h,(snoc a t)); snoc 4 (CONS(1,CONS(2,NIL))); CONS(1,CONS(2,CONS(4,NIL))):int mylist rev (CONS(1,CONS(2,NIL))); val it = CONS(2,CONS(1, NIL)) : int mylist • Write rev function to reverse a mylist. • Function snoc places an ’el at end of a mylist. Modern Programming Languages - Chapter 11

  44. Defining Operators (A Peek) • ML allows new operators to be defined • infixr 5 CONS;defines CONS to be right-associative with precedence 5, the same as :: • Higher number equals higher precedence infixr 5 CONS;1 CONS 2 CONS NIL;val it = 1 CONS 2 CONS NIL : int mylist fun add (x, y) = x + y;fun mul (x, y) = x * y;infixr 3 add;infixr 4 mul;2 add 4 mul 5;val it = 22 : int Modern Programming Languages - Chapter 11

  45. C++ tree Implementation struct tree { tree *left, *right; char data;};void f(tree *t) { if(t != NULL) { cout << t->data; f(t->left); f(t->right); }}void main ( void ){ tree l1={NULL,NULL,'1'}, l2={NULL,NULL,'2'}, r2={NULL,NULL,'3'}, r1={&l2,&r2,'*'}, t={&l1,&r1,'-'}; f(&t);} Output: -1*23 _ / \1 * / \ 2 3 Modern Programming Languages - Chapter 11

  46. Java tree Implementation public class ExampleTree { static void f(tree t) { if(t != null) { System.out.println(t.data); f(t.left); f(t.right); } } public static void main ( String args[] ){ tree l1=new tree(null,null,'1'), l2=new tree(null,null,'2'), r2=new tree(null,null,'3'), r1=new tree(l2,r2,'*'), t=new tree(l1,r1,'-'); f(t); } } class tree { public tree left, right; public char data; public tree(tree left, tree right, char data) { this.left=left; this.right=right; this.data=data; } }; Output: -1*23 _ / \1 * / \ 2 3 Modern Programming Languages - Chapter 11

  47. Java tree Implementation datatype 'data tree = Empty | Node of 'data tree * 'data * 'data tree; val l1=Node(Empty,"1",Empty); val l2=Node(Empty,"2",Empty); val r2=Node(Empty,"3",Empty); val r1=Node(l2,"*",r2); val t=Node(l1,"-",r1); fun f Empty = "" | f (Node (l,d,r)) = d ^ f l ^ f r; f t; Output: -1*23 _ / \1 * / \ 2 3 Modern Programming Languages - Chapter 11

  48. Polymorphic Binary Tree datatype 'data tree = Empty | Node of 'data tree * 'data * 'data tree; Some values of type int tree: Modern Programming Languages - Chapter 11

  49. Constructing Those Values val treeEmpty = Empty;val treeEmpty = Empty : 'a treeval tree2 = Node(Empty,2,Empty);val tree2 = Node (Empty,2,Empty) : int treeval tree123 = Node(Node(Empty,1,Empty),2, Node(Empty,3,Empty)); 2 1 3 Empty Empty Empty Empty Modern Programming Languages - Chapter 11

  50. Increment All Elements 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 3 2 4 Empty Empty Empty Empty Modern Programming Languages - Chapter 11

More Related