(* Note that in response to the prompt you may give the command use("filename"); to have the system input the file whose name is filename and continue running. New definitions will replace old ones. *) let (* An example - UNIX - to show types *) fun pair x y z = z x y; fun f1 y = pair y y; fun f2 y = f1 (f1 y); fun f3 y = f2 (f2 y); in f3 (fn x => x) end; (* Material on datatypes *) abstype ('a,'b) Assoc = assoc of ('a * 'b) list with exception not_found; local fun lookup' (x,nil) = raise not_found | lookup' (x, (y,z)::rest) = if x=y then z else lookup'(x,rest); in fun lookup (x, assoc A) = lookup' (x,A) end; fun update (a,b,assoc A) = assoc ((a,b)::A); val empty = assoc nil; end; (* Tail recursion material *) fun length x = if null x then 0 else 1 + length(tl x); fun length [] = 0 | length (h::t) = 1 + length t; (* Use of conditional: fun alength (x,n) = if null x then n else alength(tl x,n+1); *) (* Use of pattern matching: *) fun lengthaux ([],n) = n | lengthaux (h::t,n) = lengthaux(t,n+1); fun length x = lengthaux(x,0); (* NOT tail recursive: fun sumlist [] = 0 | sumlist (h::t) = h + sumlist(t); *) (* TAIL RECURSUVE: *) fun sumaux (h::t,n) = sumaux (t,h+n) | sumaux ([],n) = n:int; fun sumlist x = sumaux (x,0) (* A famous functional programming function: *) fun accumulate f a (h::t) = accumulate f (f a h) t | accumulate f a [] = a; (* Examples using accumulate: *) fun plus x y:int = x+y; val sumlist = accumulate plus 0; val length = let fun count1 n a = n+1 in accumulate count1 0 end; (* Very slow non-tail-recursive: *) fun fibnum 0 = 0 | fibnum 1 = 1 | fibnum n = fibnum(n-1) + fibnum(n-2); (* Fast tail-recursive method: *) fun fastfib n = accfib (0,1,n) and accfib (a,b,0) = a | accfib (a,b,n) = accfib(b,a+b,n-1); fibnum(30); fastfib(30);