问题
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?
回答1:
Two problems with the first version of your code:
- You're declaring a function in your let block which is never used, and your function recursively calls itself until the first argument is an empty list, so your code can be simplified to
fun makeBST _ _ = EMPTY
, so this is probably the reason for the error you're receiving because SML doesn't know what typeEMPTY
is supposed to be. - Double quotes on line 3 which should be a single quote
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;
来源:https://stackoverflow.com/questions/9954177/standard-ml-make-bst-out-of-a-list