CSC324- TUTORIAL 5 ML Shems Saleh* *Some slides inspired by/based on Afsaneh Fazly s slides
Assignment 1 2 More questions were added Questions regarding the assignment?
Starting ML Who am I? Shems Saleh shems.saleh@mail.utoronto.ca What will we do today? SML Terminal use Instructions on use found here: http://www.cs.toronto.edu/~bonner/courses/2014f/csc324/handouts/usingml.txt Useful Tools ssh Putty, Filezilla (PC), terminal, Cyberduck/Filezilla (Mac), Sublime: SFTP/FTP package control ML currying, pattern recognition, more on types (userdefined/enumerated/variant/recursive), Let and exceptions Questions?
CURRYING
Currying in ML fun sum x y = x + y; is short form for: fun sum x = (fn y => x + y) So its type is: val sum = fn: int -> int -> int Note: this means int -> (int -> int), i.e. sum takes an int and returns a function of type int -> int. i.e. sum 2 would return a function
Back to functions for a quick note fun and fn are both short for function but with different meaning: fun is used for function declaration bind identifier to function Fn is used to introduce a value of type function.
Back to currying Compare sum1 and sum2: fun sum1 x y = x + y; val sum1 = fn: int -> int -> int fun sum2(x,y) = x + y; val sum2 = fn: int * int -> int What s the difference? Currying allows us to use partially instantiated functions
PATTERN MATCHING
Pattern Matching - val mytuple = ("foo", "bar"); val mytuple = ("foo","bar") : string * string - val (x,y) = mytuple; val x = "foo" : string val y = "bar" : string - val mylist = [1,2,3,4]; val mylist = [1,2,3,4] : int list -val h::r = mylist; val h = 1 : int val r = [2,3,4] : int list
Pattern Matching _ is don t care matches everything, binds nothing Examples: - val (first, _) = mytuple; val first = "foo" : string - val h::_ = [1,2,3]; val h = 1 : int
Pattern Matching Write the following function using pattern matching: fun len lst = if (null lst) then 0 else 1 + len (tl lst);
Pattern Matching Solution fun len [] = 0 len (x::xs) = 1 + len xs;
Pattern Matching Note If you didn t consider all the cases in your pattern matching function, you ll get a nonexhaustive exception Example: - fun len (x::xs) = 1 + len xs; stdin... Warning: match nonexhaustive x :: xs =>... val len = fn : 'a list -> int
Exercise Write a function firstlist that takes a list of pairs, and returns a new list consisting of the rst elements of all pairs. For example: firstlist [] ==> [] firstlist [(1,2),(1,3)] ==> [1,1] firstlist [(1,"a"),(2,"b"),(3,"c")] ==> [1,2,3] firstlist [([],"a"),([1],"b"),([1,2],"c")] ==> [[],[1],[1,2]]
Solution fun firstlist [] = [] firstlist ((e1,e2)::es) = e1::(firstlist es);
Last Note Regarding Pattern Matching Since ML is typed, the following 2 rules must always be followed: All patterns must have the same type All return values must have the same type
QUESTIONS?
USING LET IN ML
Let Expression Syntax let statements in body-expression end
Let Example fun reverse lst = let fun reverseacc [] acc = acc reverseacc (x::xs) acc = reverseacc xs (x::acc) in reverseacc lst [] end; reverse : 'a list -> 'a list - reverse [1,2,3]; val it = [3,2,1] : int list
TYPING
Type synonyms We can give existing types new names: Examples -type float = real; type float = real -type count = int and average = real; type count = int type average = real -val f : float = 2.3; val f = 2.3: float -val i = 3 : count; val i = 3: count
User-Defined Datatypes Syntax datatype type = constructor of pre-defined type constructor2 of pre-defined type 2 Type is omitted if constructor is constant (doesn t need arguments
Type Examples -datatype fruit = Apple Orange Banana; datatype fruit = Apple Orange Banana - val c = Apple; Val c = Apple : fruit fun fruitstr Apple = apple Orange = orange Banana = banana ; Note this is an enumerated type
Variant types You can create a datatype that contains multiple different pre-defined types within it Example datatype number = R of real I of int; val n1 = I 2; val n2 = R 3.0; val lst = [R 2.2, I 3, I 4, R 0.1]; (* val lst = [R 2.2,I 3,I 4,R 0.1] : number list *)
Exercise datatype number = R of real I of int; val lst = [R 2.2, I 3, I 4, R 0.1]; Write a function sumints that takes a number list and returns the sum of the integers:
Solution fun sumints [] = 0 sumints ((I x)::rest) = x + sumints rest sumints ((R x)::rest) = sumints rest; sumints : number list -> int;
Recursive Types Example datatype llist = Nil Node of int * llist; (* constructing instances of the linked list *) val x = Nil; val y = Node(5,Nil); val z = Node(3, Node(2, Node(1,Nil)));
Polymorphic datatype 'a llist = Nil Node of 'a * ('a llist);
MUTUAL RECURSION
Mutual recursion Example fun even 0 = true even x = odd (x - 1) and odd 0 = false odd x = even (x - 1); even : int -> bool; odd : int -> bool Note: and vs. andalso
EXCEPTIONS
Exceptions Definition and Use exception factneg of int; fun robustfact n= let fun fact 0 = 1 fact n = n * fact (n-1); in if n < 0 then raise factneg n else fact n end;
THANK YOU FOR YOUR ATTENTION See you next week