(* Some example of polymorphic datatypes and functions that compute on them. From lectures on 29 April 2001. *) (* The option datatype is already defined in SML *) datatype 'a option = NONE | SOME of 'a; (* define aux and index at same level *) fun aux(c, x, y::l) = if x = y then SOME c else aux(c+1, x, l) | aux(c, x, nil) = NONE; fun index(x,l) = aux(1,x,l); (* define aux local to index *) fun index(x,l) = let fun aux(c, x, y::l) = if x = y then SOME c else aux(c+1, x, l) | aux(c, x, nil) = NONE in aux(1,x,l) end; (* Compare the following disjunctive type to the "conjunction" pair type. *) datatype ('a, 'b) or = left of 'a | right of 'b; fun cases(f, g, left x) = f x | cases(f, g, right x) = g x; val add1list = map (fn x => cases( (fn x => left(x + 1)), (fn x => right(x + 1.0)), x)); (* Recall the definition of reduce. *) fun reduce (nil, f, v) = v | reduce (x::L, f, v) = f(x,reduce(L,f,v)); (* The following is an implementation of the bsort program using an implementation of binary, integer labeled trees *) datatype btree = Empty | Node of int * btree * btree; fun insert(n,Empty) = Node(n,Empty,Empty) | insert(n,Node(m,Left,Right)) = if n <= m then Node(m,insert(n,Left),Right) else Node(m,Left,insert(n,Right)); fun insertList L = reduce(L,insert,Empty) (* We use the above instead of the following. They are equivalent programs. fun insertList nil = Empty | insertList(n::l) = insert(n,insertList l); *) fun in_order_traversal Empty = nil | in_order_traversal(Node(n,Left,Right)) = in_order_traversal Left @ (n::in_order_traversal Right); fun bsort L = in_order_traversal (insertList L); val ex1 = insert(10, insert(8, insert(5, insert(9,Empty)))); (* We now rewrite this bsort program to make it polymorphic and to hide all the auxillary declarations *) local datatype 'a tree = Empty | Node of 'a * 'a tree * 'a tree fun insert(n,Empty,ord) = Node(n,Empty,Empty) | insert(n,Node(m,Left,Right),ord) = if ord(n,m) then Node(m,insert(n,Left,ord),Right) else Node(m,Left,insert(n,Right,ord)) fun insertList(L,ord) = reduce(L, (fn (x,l) => insert(x,l,ord)), Empty) fun in_order_traversal Empty = nil | in_order_traversal(Node(n,Left,Right)) = in_order_traversal Left @ (n::in_order_traversal Right) in fun bsort(L,ord) = in_order_traversal (insertList(L,ord)); end;