fun curry f x y = f(x,y); val $ = curry; fun add x y = x + y; add 1 2; (*add 1.1 2.2;*) fun first x y = x; val One = first 1; (*One 2;*) (* equality poymorphism *) fun same x y = (x = y); same 1 2; same 1 1; same "gato" "gato"; (* True polymorphism *) (* C or Java: Ad Hoc polymorphism *) (* function composition with two arguments *) (* fun (f oo g) x y = f (g x y); *) fun add x y = x + y; fun mul x y = x * y; fun double x = 2 * x; (* second element *) val second = hd o tl; (* apply a function twice *) fun twice f = f o f; twice double 4; fun square x = x * x; val divd = $ op/; val inverse = $ op/ 1.0; val f1 = inverse o real o square; f1 2; (* combinators *) fun I x = x; (* identity *) fun K x y = x; (* select *) fun S x y z = x z (y z); (* composition *) val square = S mul I; square 5; (* Higher order functions for lists *) (* map: apply function f to each element in the list *) fun map (f:'a->'b) (nil:'a list) :('b list) = [] | map f (x::xs) = (f x) :: map f xs; (* filter: return a list where the elements pass test f *) fun filter (f:'a->bool) (nil:'a list) :('a list)= [] | filter f (x::xs) = if f x then x :: filter f xs else filter f xs; (* reduce: combine all the elments in the list *) (* u is the identity element for operation f *) fun reduce (f:'a->'b->'b) (u:'b) (nil:'a list) :'b = u | reduce f u (x::xs) = f x (reduce f u xs); (* create a list of integers from lo to hi*) fun fromTo lo hi = if lo > hi then [] else lo :: fromTo (lo+1) hi; (* create a list of integers from 0 to ...*) val upto = fromTo 0; (* more complex function *) fun combine nil nil = [] | combine (x::xs) (y::ys) = (x, y) :: combine xs ys; combine [1, 2, 3] [10, 20, 30]; (* flipadd takes one pascal list and generates the next *) fun flipadd xs = map (op +) (combine ([0] @ xs) (xs @ [0])); flipadd [1]; flipadd [1, 1]; flipadd [1, 2, 1]; flipadd [1, 3, 3, 1]; (* generates "n" lists start is the "seed" list function "next" generates a next list based on the previous one *) fun genlist start next 0 = nil | genlist start next n = start :: genlist (next start) next (n-1); (* generates n pascal lists *) val pascal = genlist [1] flipadd; pascal 4; (* prime numbers example *) fun divides n i = (n mod i = 0); fun factors n = filter (divides n) (fromTo 2 (n - 1)); factors 50; (* test if something is null *) fun null x = (x = nil); (* test for primality *) (* the list of all numbers that divide n is null *) val prime = null o factors; (* make a list of prime numbers *) val primes = filter prime o upto; (* use it *) primes 20; (* From Watt *) fun sqr x:real = x * x; val pi = 3.1415; datatype shape = point | circle of real | box of (real * real); fun area (point) = 0.0 | area (circle r) = pi * sqr (r) | area (box (w, h)) = w * h; val myBox = box(3.0, 4.0); area myBox; (* From Michaelson *) datatype booleanValue = true | false; datatype traffic_light = red | red_amber | green | amber; fun change red = red_amber | change red_amber = green | change green = amber | change amber = red; change red; datatype inttree = empty | node of int * inttree * inttree; fun tadd (v:int) empty = node(v, empty, empty) | tadd (v:int) (node(nv:int, l:inttree, r:inttree)) = if v < nv then node (nv, tadd v l, r) else node (nv, l , tadd v r); (* use it *) val root = empty; val root = tadd 5 root; val root = tadd 3 root; val root = tadd 7 root; val root = tadd 4 root; val root = tadd 9 root; (* from tree.ml *) datatype 'a tree = Lf | Br of 'a * 'a tree * 'a tree; val tree1 = Br( 1, Br(2, Lf, Lf), Br(3, Lf, Br(4, Lf, Lf))); (* count non-leaf nodes *) fun count (Lf) = 0 | count (Br(v, t1, t2)) = 1 + count t1 + count t2; count tree1; (* depth of the tree *) fun max (x:int, y:int):int = if x > y then x else y; fun depth (Lf) = 0 | depth (Br(v, t1, t2)) = 1 + max( depth t1, depth t2 ); depth tree1; (* list with an inorder traversal of the tree *) fun getin (Lf) = [] | getin (Br(v, t1, t2)) = getin(t1) @ [v] @ getin(t2); getin tree1;