When it came to finding a value in a bst env all I had to do was compare the value I was looking for with the root value at a node
type 'a tenv = (name * 'a) btree
exception NotFound of name
fun find compare name Leaf = raise NotFound name
| find compare name (Node (lt, (key, value), rt)) =
case compare(name, key) of
LESS => find compare name lt
| GREATER => find compare name rt
| EQUAL => value
But in a function represented env instead of a bst with nodes and leafs the find function is of type
name * 'a fenv -> 'a
and
type 'a fenv = name -> 'a
I get the general idea of the function but I'm confused as to how I would traverse the environment looking for the name. Bst has a node and a tree like structure. Can someone just give an explanation if possible?
EDITED IN
My working implementation is as such
exception NotFound of name
val Empty = fn name => raise NotFound name
fun Find(name, env) = env name
fun Bind(name, data, rho) = fn key => if key = name then data else rho
key
So an environment is now represented as a function that takes a name and either returns its value in the environment or raises an exception.
This function is going to be a composition of functions, and you "traverse" it by applying functions that represent older environments.
(This sounds more complicated than it is, but it can take a while to wrap your head around it.)
You can create the empty environment by writing a function that takes a name and raises an exception:
Finding things is much shorter than a tree lookup, since the environment already is that function:
What remains is insertion:
It has to be a function that takes a name, since that's what an environment is
If
n
is the same askey
, that function should returnvalue
:n
might be found in the rest of the environment, so we apply that function in order to look for it there:And that's, as they say, it.
In a sense, the "traversal" code has moved from the lookup function to the insertion function.
Test:
As you can see, representing things as functions can be extremely compact.
In order to see what's happening, let's expand the first example:
Which is the same as (expanding the definition of
insert
):Successful lookup:
is
which is
Failure:
Exception-handling example:
If you don't handle the exception, you will get an "uncaught exception" error, as in the example above.
You need to handle the exception in the code that uses
find
.A trivial example: