(* run with mosml or sml *) (* simple expressions *) (3 + 5) * 2; [(3,4),(5,6)]; if true then 3 else 4; (* declarations *) val a = 3 and b = 5 and c = 2; (a + b) div c; (* functions *) val f = fn x => x + 1; val g = fn (a,b) => (a + b) div 2; (f 3, g(8,4)); (f, f 3); val h = g; (* static scope, deep binding *) val f = fn x => a + x; val a = [1,2,3]; f 1; let val a = 3 and b = 5 in (a + b) div 2 end; (* lists *) nil; 1 :: [2,3]; 1 :: 2 :: 3 :: nil; null []; null[1,2,3]; hd [1,2,3]; tl [1,2,3]; [1,2] @ []; [] @ [3,4]; [1,2] @ [3,4]; (* functions *) val plus = fn (a,b) => a + b; let val x = (3,4) in plus x end; val plus = fn x => let val (a,b) = x in a + b end; (* "let" is syntactic sugar for immediate application of an anonymous function let a = exp in body end; means the same thing as (fn a => body) exp *) (fn x => plus x) (3, 4); (* with patterns *) val f = fn [x,y,z] => (x,y,z); (* why is this pattern not exhaustive? *) val (a,b,c) = f[1,2,3]; val f = fn [x,y,z] => (x,y,z) | [x,y] => (x,y,0) | [x] => (x,0,0) | [] => (0,0,0) | x :: y :: z :: _ => (z,y,x) ; (* recursive functions *) val rec factorial = fn n => if n = 0 then 1 else n * factorial(n-1); (* case analysis in functions *) val rec summation = fn nil => 0 | (head :: tail) => head + summation tail; (* to here *) (* polymorphic with type identifier *) val rec length = fn nil => 0 | (_ :: tail) => 1 + length tail; (length [1,2,3], length ["a","b","c","d"]); val swap = fn (x,y) => (y,x); (* list functions are polymorphic *) nil; null; hd; tl; (* higher order functions *) val times = fn a => (fn b => a * b); times 3 4; val twice = times 2; twice 4; val comp = fn (f,g) => (fn x => f (g x)); val fourtimes = comp(twice,twice); fourtimes 5; (* currying *) val plus = fn (a, b) => a + b: int; val curry = fn f => fn a => fn b => f(a,b); val curryplus = curry plus; val successor = curryplus 1; curryplus 3; curryplus 3 4; successor 12; (* datatypes *) datatype money = nomoney | coin of int | bill of int | check of string * int; val nickel = coin 5 and dime = coin 10 and quarter = coin 25; fun amount nomoney = 0 | amount (coin cents) = cents | amount (bill dollars) = 100 * dollars | amount (check(bank,cents)) = cents; (* a single type constructor has the same name as datatype by convention *) datatype point = point of int * int; (* polymorphic datatypes *) datatype 'a predicate = predicate of 'a -> bool; datatype ('a,'b) leftprojection = leftprojection of ('a * 'b) -> 'a; (* recursive datatypes *) datatype 'a myList = empty | cons of 'a * 'a myList; (* vim:nospell:filetype=sml *)