I'm working through the book Modern Compiler Implementation in ML, and learning sml at the same time.
I'm stumped by one of the exercises (1.1.b) in the first chapter. We are asked to implement a binary tree which maintains key/value pairs, with keys being strings, and values being a parameterized type. My data type is defined as follows
type key = string
datatype 'a tree = LEAF | TREE of 'a tree * key * 'a * 'a tree
We are asked to implement a lookup function whose type is 'a tree * key -> 'a.
I don't know how to implement this function because I don't know what to return when the tree is a LEAF. There is no default value of 'a. The instructions in the book don't say way to do if the key is not found, but it insists the function MUST return type 'a.
Is this just an error in the book, or is there a correct way to do this in sml?
I toyed with trying to raise an exception in this case, but the compiler apparently won't let me throw an exception without catching it.
If I were implementing this in Scala, I'd change the return type to Option[A] and return None if the key is not found; or in Common Lisp, I'd pass a continuation to call with the found value, and then simply not call the continuation if the key is not found.
Here is my code, which is not yet working.
(* page 12, exercise 1.1 b *)
type key = string
datatype 'a tree = LEAF | TREE of 'a tree * key * 'a * 'a tree
val empty = LEAF
fun insert(key,value,LEAF) = TREE(LEAF,key,value,LEAF)
| insert(key,value,TREE(l,k,v,r)) =
if key<k
then TREE(insert(key,value,l),k,v,r)
else if key>k
then TREE(l,k,v,insert(key,value,r))
else TREE(l,key,value,r)
fun lookup(LEAF,key) = (* !!!HELP!!! I don't know what to do in this case *)
| lookup(TREE(l,k,v,r),key) = if k=key
then v
else if key<k
then lookup(l,key)
else lookup(r,key)
val t1 = insert("a",1,empty)
val t2 = insert("c",2,t1)
val t3 = insert("b",3,t2)
;
lookup(t3,"a");
lookup(t3,"b");
lookup(t3,"c");
lookup(t3,"d");
BTW, I don't understand why emacs sml-mode insists on indenting the calls to lookup.