CS 541 Lecture -*- Outline -*- * Built-in types of SML ad: these are needed for all programming in SML effect: understand built-in types and their operations understand different kinds of recursion and their importance ** Fundamental classification of objects *** atomic data (section 2.4 in Paulson's book) types: bool, int, real, string e.g.: true, false, 1, ~2, 27.3, "a string", "", use C style escapes for strings reals must have digits on either side of decimal point *** structured types (page 25...) types: pairs, tuples, unit, records, lists e.g.: (1,true), (1,true,2.7), (), {name = "Gary", weight=135}, [], [1,2,3] lists: homogeneous sequence of objects enclosed by brackets make a table as discuss the following: type constructors observers string "" : -> string = : string*string -> bool size : string -> int ** string ---------------------- - "ab"; val it = "ab" : string - chr(97); val it = "a" : string - ord("a"); val it = 97 : int - ordof("abc",2); val it = 99 : int - "ab" = "ab"; val it = true : bool - "a" = "b"; val it = false : bool - "a" < "b"; val it = true : bool - explode("abc"); val it = ["a","b","c"] : string list - implode(["a","b","c"]); val it = "abc" : string - substring("abcde",2,3); val it = "cde" : string ---------------------- ** bool ---------------------- - true; val it = true : bool - false; val it = false : bool - not(true); val it = false : bool - not false; val it = true : bool ----------------------- ----------------------- - val e1 = "val-e1"; val e1 = "val-e1" : string - val e2 = "val-e2"; val e2 = "val-e2" : string - if true then e1 else e2; val it = "val-e1" : string - if false then e1 else e2; val it = "val-e2" : string ---------------------- ---------------------- be1 andalso be2 =def= if be1 then be2 else false be1 orelse be2 =def= if be1 then true else be2 ---------------------- *Note: 'if' is not strict (so neither is 'andalso' nor 'orelse')* andalso and orelse require their arguments to be be booleans, they are not functions ** pairs, tuples, and unit --------------------- - (1,true); val it = (1,true) : int * bool - (1,2,3); val it = (1,2,3) : int * int * int - (1,(2,3)); val it = (1,(2,3)) : int * (int * int) - (1,(true,2.8)); val it = (1,(true,2.8)) : int * (bool * real) - ((1,true),2.8); val it = ((1,true),2.8) : (int * bool) * real - (1); val it = 1 : int - (); val it = () : unit - ("zero tuple:",()); val it = ("zero tuple:",()) : string * unit ---------------------- so ( , ) makes pairs and tuples. Why this notation? idea is that in a functional language want only 1 argument and result for functions f(x,y) is interpreted as f applied to the pair (x,y) *** binding, pattern matching, and simple functions No built-in operations on pairs! have to use pattern matching to pick them apart -------------------- - fst (1,2); std_in:16.1-16.3 Error: unbound variable or constructor fst - val (x,y) = (1,true); val x = 1 : int val y = true : bool - x; val it = 1 : int - y; val it = true : bool - fun fst(x,y) = x; val fst = fn : 'a * 'b -> 'a - fst(1,2); val it = 1 : int - val snd = fn (x,y) => y; val snd = fn : 'a * 'b -> 'b - snd (true,"neat, eh?"); val it = "neat, eh?" : string - fun average(x,y) = (x+y)/2.0; val average = fn : real * real -> real - average(3.0,50.0); val it = 26.5 : real - fun mult_add((x,y),z) = x*y + z + 1; val mult_add = fn : (int * int) * int -> int - mult_add((3,4),5); val it = 18 : int - mult_add(3,4,5); std_in:3.1-3.15 Error: operator and operand don't agree (tycon mismatch) operator domain: (int * int) * int operand: int * int * int in expression: mult_add (3,4,5) - fun max3(a,b,c) = max(a,max(b,c)); val max3 = fn : int * int * int -> int - max3(4,7,6); val it = 7 : int ----------------- records are very similar, see section 2.9 for details ------------------ - {a = 2, b = "true", c}; std_in:15.22 Error: syntax error found at RBRACE - {a = 2, b = "true", c = 3.5}; val it = {a=2,b="true",c=3.5} : {a:int,b:string,c:real} - val r = {a = 2, b = "true"}; val r = {a=2,b="true"} : {a:int,b:string} - r.a; std_in:3.1-3.3 Error: unbound structure r in path r.a - val {a=x, b=y} = r; val x = 2 : int val y = "true" : string ------------------ ** lists (chapter 3) ---------------------- - val x = "x"; val x = "x" : string - val y = "y"; val y = "y" : string - val lst = ["a","b","c"]; val lst = ["a","b","c"] : string list - val lst2 = [["d"],["e"]]; val lst2 = [["d"],["e"]] : string list list - - nil; val it = [] : 'a list - []; val it = [] : 'a list - 9 :: []; val it = [9] : int list - - "hi" :: lst; val it = ["hi","a","b","c"] : string list - hd lst; val it = "a" : string - tl lst; val it = ["b","c"] : string list - lst; val it = ["a","b","c"] : string list - val head :: tail = lst; std_in:4.1-4.22 Warning: binding not exhaustive head :: tail = ... val head = "a" : string val tail = ["b","c"] : string list - val (head :: tail) = lst; std_in:5.1-5.24 Warning: binding not exhaustive head :: tail = ... val head = "a" : string val tail = ["b","c"] : string list - - hd (x :: lst); val it = "x" : string - tl (y :: lst); val it = ["a","b","c"] : string list - (hd lst) :: (tl lst); val it = ["a","b","c"] : string list - - null []; val it = true : bool - null (x :: lst); val it = false : bool ------------------ Q: can you define hd, tl, and null?