######### Playing with anonymous functions ################# - (fn x => x*x); > val it = fn : int -> int - (fn x => x*x) 2; > val it = 4 : int - round; > val it = fn : real -> int - real; > val it = fn : int -> real - real 1; > val it = 1.0 : real - round 1.5; > val it = 1 : int - (real o round); > val it = fn : real -> real - (real o round) 2.1; > val it = 2.0 : real - real (round 2.1); > val it = 2.0 : real - (1,2); > val it = (1, 2) : int * int - (1,true); > val it = (1, true) : int * bool - (2,false,3.0,"a"); > val it = (2, false, 3.0, "a") : int * bool * real * string - (fn (a,b) => a+b); > val it = fn : int * int -> int - val add = (fn (a,b) => a+b); > val add = fn : int * int -> int - add (2,3); > val it = 5 : int - (fn (a,b) => (b,a)) (true,1); > val it = (1, true) : int * bool - (fn a => (fn b => a+b)) 1 2; > val it = 3 : int - val add2 = (fn a => (fn b => a+b)); > val add2 = fn : int -> int -> int - add2 2 3; > val it = 5 : int - add2 4; > val it = fn : int -> int - val inc = add2 1; > val inc = fn : int -> int - inc 2; > val it = 3 : int - inc 3; > val it = 4 : int - fun add (a,b) = a+b; > val add = fn : int * int -> int - fun add2 a b = a+b; > val add2 = fn : int -> int -> int ######### Playing with if-then-else ################# - val b = 2; > val b = 2 : int - if b>1 then "happy" else "unhappy"; > val it = "happy" : string - op>; > val it = fn : int * int -> bool - b>2; > val it = false : bool - fun ifthenelse(true,e1,e2)=e1 | ifthenelse(false,e1,e2)=e2; > val 'a ifthenelse = fn : bool * 'a * 'a -> 'a - ifthenelse(b>1,"happy","unhappy"); > val it = "happy" : string - op^; > val it = fn : string * string -> string - "a"^"b"; > val it = "ab" : string - op^("a","b"); > val it = "ab" : string - "I am " ^ (if b>1 then "happy" else "unhappy"); > val it = "I am happy" : string - 1+(if b>1 then 1 else 2); > val it = 2 : int ######### Playing with infix operators ################# - fun op++ (a,b) = a+b; > val ++ = fn : int * int -> int - infix 2 ++; > infix 2 ++ - 2*3++1; > val it = 7 : int - infix 9 ++; > infix 9 ++ - 2*3++1; > val it = 8 : int - infix 9 +; > infix 9 + - 2*3+1; > val it = 8 : int ######### Playing with let-in-end ################# - let val a = 1 in a+1 end; > val it = 2 : int - let val a = 1 val b = 2 in a+b end; > val it = 3 : int - let val a = 1 val b = 2 in a+b end +1; > val it = 4 : int - 1+let val a = 1 val b = 2 in a+b end; > val it = 4 : int - let val a = "apple" val b = "tree" in a^b end; > val it = "appletree" : string ######### Playing with polymorphism ################# - fun f x=x+1; > val f = fn : int -> int - fun id x = x; > val 'a id = fn : 'a -> 'a - id 1; > val it = 1 : int - id true; > val it = true : bool - fun swap (a,b) = (b,a); > val ('a, 'b) swap = fn : 'a * 'b -> 'b * 'a - fun swap (a,b) = (b,a+1); > val 'a swap = fn : int * 'a -> 'a * int - fun eq (x, y) = x = y; > val ''a eq = fn : ''a * ''a -> bool ######### Playing with lists ################# - []; > val 'a it = [] : 'a list - nil; > val 'a it = [] : 'a list - op::(1,[]); > val it = [1] : int list - 1::[]; > val it = [1] : int list - 1::(2::[]); > val it = [1, 2] : int list - (1::[])::[]; > val it = [[1]] : int list list - [1]; > val it = [1] : int list - [[1],[1,2]]; > val it = [[1], [1, 2]] : int list list - 1::[]; > val it = [1] : int list - 1.0::[1]; ! Toplevel input: ! 1.0::[1]; ! ^ ! Type clash: expression of type ! int ! cannot have type ! real - op::; > val 'a it = fn : 'a * 'a list -> 'a list - 1::(2::[]); > val it = [1, 2] : int list - 1::2::[]; > val it = [1, 2] : int list - (1::2)::[]; ! Toplevel input: ! (1::2)::[]; ! ^ ! Type clash: expression of type ! int ! cannot have type ! int list - (1::2); ! Toplevel input: ! (1::2); ! ^ ! Type clash: expression of type ! int ! cannot have type ! int list - (1::[]); > val it = [1] : int list - fun hd (x :: _) = x; ! Toplevel input: ! fun hd (x :: _) = x; ! ^^^^^^^^^^^^^^^ ! Warning: pattern matching is not exhaustive > val 'a hd = fn : 'a list -> 'a - hd [1]; > val it = 1 : int - hd [1,2,3]; > val it = 1 : int - hd []; ! Uncaught exception: ! Match - fun tl (_ :: xs) = xs; ! Toplevel input: ! fun tl (_ :: xs) = xs; ! ^^^^^^^^^^^^^^^^^ ! Warning: pattern matching is not exhaustive > val 'a tl = fn : 'a list -> 'a list - tl [1,2,3]; > val it = [2, 3] : int list - fun isempty [] = true | isempty (_::_) = false; > val 'a isempty = fn : 'a list -> bool - isempty [1,2]; > val it = false : bool - isempty []; > val it = true : bool - fun last (x::[]) = x | last (x::xs) = last xs; ! Toplevel input: ! fun last (x::[]) = x | last (x::xs) = last xs; ! ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ! Warning: pattern matching is not exhaustive > val 'a last = fn : 'a list -> 'a - last [1,2,3]; > val it = 3 : int - map (fn x => x+1) [1,2,3]; > val it = [2, 3, 4] : int list - map (fn x => x+1); > val it = fn : int list -> int list - val listincr = map (fn x => x+1); > val listincr = fn : int list -> int list - listincr [1,2,3]; > val it = [2, 3, 4] : int list - val a = [1,2,3]; > val a = [1, 2, 3] : int list - listincr a; > val it = [2, 3, 4] : int list - a; > val it = [1, 2, 3] : int list ######### strings and char lists ################# - chr; > val it = fn : int -> char - ord; > val it = fn : char -> int - val chrinc = (fn x => chr (ord x +1)); > val chrinc = fn : char -> char - chrinc #"a"; > val it = #"b" : char - fun stringmap f l = implode ( map f (explode l)); > val stringmap = fn : (char -> char) -> string -> string - stringmap chrinc "apple"; > val it = "bqqmf" : string - load "Char"; > val it = () : unit - Char.toUpper; > val it = fn : char -> char - stringmap Char.toUpper "apple"; > val it = "APPLE" : string - fun filter _ [] = [] | filter p (x :: xs) = if p x then x :: filter p xs else filter p xs; > val 'a filter = fn : ('a -> bool) -> 'a list -> 'a list - filter Char.isUpper (explode "aPPle"); > val it = [#"P", #"P"] : char list - implode (filter Char.isUpper (explode "aPPle")); > val it = "PP" : string - fun stringMax (s : string, t) = if s > t then s else t; > val stringMax = fn : string * string -> string - fun maxl max [] = raise Empty | maxl max [z] = z | maxl max (z::zs) = max(z, maxl max zs); > val 'a maxl = fn : ('a * 'a -> 'a) -> 'a list -> 'a - maxl stringMax ["apple","pear","plum"]; > val it = "plum" : string ######### records and datatypes ################# - {x=2, y=1.0}={y=1.0,x=2}; > val it = true : bool - {1 = 2, 2 = 1.0}; > val it = (2, 1.0) : int * real - {1 = 2, 2 = 1.0, x=true}; > val it = {x = true, 1 = 2, 2 = 1.0} : {x : bool, 1 : int, 2 : real} - {1 = 2, 2 = 1.0, 4=true}; > val it = {1 = 2, 2 = 1.0, 4 = true} : {1 : int, 2 : real, 4 : bool} - {1 = 2, 2 = 1.0, 4=true, 3=[]}; > val 'a it = (2, 1.0, [], true) : int * real * 'a list * bool - type rat = {num : int, den : int}; > type rat = {den : int, num : int} > val it = 2 : int - fun denominator {num=x,den=y} = y; > val ('a, 'b) denominator = fn : {den : 'a, num : 'b} -> 'a - denominator {num=2,den=3}; > val it = 3 : int - {num=2,den=3}; > val it = {den = 3, num = 2} : {den : int, num : int} - {num=2,den=3}:rat; > val it = {den = 3, num = 2} : {den : int, num : int} - #den{num=2,den=3}; > val it = 3 : int - datatype rat = Rat of {num : int, den : int}; > New type names: =rat datatype rat = (rat,{con Rat : {den : int, num : int} -> rat}) con Rat = fn : {den : int, num : int} -> rat - Rat {den=1, num=2}; > val it = Rat{den = 1, num = 2} : rat - fun denominator (Rat{den=x,num=y})=y; > val denominator = fn : rat -> int - denominator (Rat {den=1, num=2}); > val it = 2 : int - datatype answer = Yes | No; > New type names: =answer datatype answer = (answer,{con No : answer, con Yes : answer}) con No = No : answer con Yes = Yes : answer - No; > val it = No : answer - datatype 'a option = NONE | SOME of 'a; > datatype 'a option = NONE | SOME of 'a - NONE; > val it = NONE : 'a option - SOME(1); > val it = SOME 1 : int option - fun id x = x; > val id = fn : 'a -> 'a - fun id x:rat option = x; > val id = fn : rat option -> rat option - id (SOME(Rat{den=1,num=2})); > val it = SOME (Rat {den=1,num=2}) : rat option - id NONE; > val it = NONE : rat option ######### the unit type ################# - (); > val it = () : unit - {}; > val it = () : unit - print "apple"; apple> val it = () : unit - fun fact 1 = 1 | fact n = n*fact(n-1); > val fact = fn : int -> int - fun fact 1 = 1 | fact n = (print (Int.toString n);n*fact(n-1)); > val fact = fn : int -> int - fact 5; 5432> val it = 120 : int - fun fact 1 = 1 | fact n = (print (Int.toString n^"\n");n*fact(n-1)); > val fact = fn : int -> int - fact 5; 5 4 3 2 > val it = 120 : int ######### foldr and folrl ################# - val isum = foldr op+ 0; > val isum = fn : int list -> int - isum [1,2,3,4]; > val it = 10 : int - foldr op+ 0 [1,2,3]; > val it = 6 : int - foldr (fn (x,y) => x andalso y) true [true,false,true]; > val it = false : bool - foldr (fn (x,y) => x andalso y) true [true,true]; > val it = true : bool - real; > val it = fn : int -> real - (fn (x,y) => real x + y); > val it = fn : int * real -> real - foldr (fn (x,y) => real x + y) 0.0 [1,2,3,4]; > val it = 10.0 : real ######### pushing the limits ################# - fun f x = f (x-1); > val 'a f = fn : int -> 'a - f 0; ! Uncaught exception: ! Overflow - fun f x = f x; > val ('a, 'b) f = fn : 'a -> 'b - f 1; > Interrupted. - fun f x = f x | f 0 = 1.0; ! Toplevel input: ! fun f x = f x | f 0 = 1.0; ! ^^^^^^^^^^^^^^^^^^^^^ ! Warning: some cases are unused in this match. > val f = fn : int -> real - fun f x = f x | f x = true; ! Toplevel input: ! fun f x = f x | f x = true; ! ^^^^^^^^^^^^^^^^^^^^^^ ! Warning: some cases are unused in this match. > val 'a f = fn : 'a -> bool - fun f x = f x; > val ('a, 'b) f = fn : 'a -> 'b - f(1) +1; > Interrupted. - fun f x = f x | f x = x; ! Toplevel input: ! fun f x = f x | f x = x; ! ^^^^^^^^^^^^^^^^^^^ ! Warning: some cases are unused in this match. > val 'a f = fn : 'a -> 'a - f(1.0)+1; ! Toplevel input: ! f(1.0)+1; ! ^ ! Type clash: expression of type ! int ! cannot have type ! real ######### function application expained ################# (* fun factorial 0 = 1 | factorial n = n * factorial(n-1) *) fun factorial 0 = 1 | factorial n = (* n * factorial(n-1) *) let val NMinus1=n-1 val FactOfNMinus1=factorial(NMinus1) in n*FactOfNMinus1 end fun factorial n = let (* factIter (p,n)= n! * p *) fun factIter (p, 0) = p | factIter (p, n) = (* factIter(p*n,n-1) *) let val PTimesN = p*n val NMinus1 = n-1 in factIter(PTimesN, NMinus1) end in factIter(1, n) end fun take (_, 0) = [] | take ([], _) = [] | take (x::xs, i) = (* x :: take(xs, i-1) *) let val IMinusOne = i-1 val TakeIMinusOne = take(xs,IMinusOne) in x::TakeIMinusOne end ############### 3 versions of takeanddrop ########################## fun takeanddrop (l,0) = ([],l) | takeanddrop ([],k)= raise Empty | takeanddrop ((x::xs),k) = let val (kminusone,remaining) = takeanddrop (xs,k-1) in ( (x::kminusone), remaining ) end fun takeanddrop2 (l,k) = let fun aux (l,0,a) = (a,l) | aux ([],k,_) = raise Empty | aux ((x::xs),k,a)= aux(xs, k-1, a@[x]) in aux (l,k,[]) end fun takeanddrop3 (l,k) = let fun aux (l,0,a) = (rev a,l) | aux ([],k,_) = raise Empty | aux ((x::xs),k,a)= aux(xs, k-1, x::a) in aux (l,k,[]) end