Reputation: 3327
I want to make a function standard ml that takes a list and function and makes a BST out of it. The function's type is: 'a list -> ('a * 'a -> bool) -> 'a tree
, but I'm having some problems with it, here are the code I wrote:
datatype 'data tree =
EMPTY
| NODE of 'data tree * 'data * "data tree;
fun makeBST [] f = EMPTY
| makeBST (x::xs) f =
let
fun insert EMPTY x = NODE(EMPTY, x, EMPTY)
| insert (NODE(left, root, right)) x =
if f(x, root) then
insert left x
else
insert right x
in
makeBST xs f
end;
The type i'm getting with this function is: 'a list -> ('b * 'c -> bool) -> 'd tree
and when I try to call it, like the following makeBST [4, 3, 6, 7, 8, 2, 0, 1] (op <);
I get the following error:
stdIn:16.1-16.40 Warning: type vars not generalized because of
value restriction are instantiated to dummy types (X1,X2,...)
val it = EMPTY : ?.X1 tree
What is wrong with the code? Thanks
EDIT:
Second version of my code:
fun makeBST [] f = EMPTY
| makeBST (x::xs) f =
let
val tree = EMPTY
fun insert EMPTY x = NODE (EMPTY, x, EMPTY)
| insert (NODE(left, root, right)) x =
if f(x, root) then
insert left x
else
insert right x
in
insert (makeBST xs f) x
end;
This code produced the type i want but is it correct?
Upvotes: 1
Views: 2431
Reputation: 644
Two problems with the first version of your code:
fun makeBST _ _ = EMPTY
, so this is probably the reason for the error you're receiving because SML doesn't know what type EMPTY
is supposed to be.Though, since you've made a second version, I'm guessing you caught this already. Your new code still isn't correct yet though. The result of any call to this function is a tree with the first element of the list as a root and two EMPTY
children. You're comparing the left and right subtree and then adding the new value at the right place, but the issue is that you only return that subtree and not the entire tree. What you want is the following:
fun makeBST [] f = EMPTY
| makeBST (x::xs) f =
let
val tree = EMPTY
fun insert EMPTY x = NODE (EMPTY, x, EMPTY)
| insert (NODE(left, root, right)) x =
if f(x, root) then
Node(insert left x, root, right)
else
Node(left, root, insert right x)
in
insert (makeBST xs f) x
end;
Upvotes: 2