我想创建一个函数标准ml,它接受一个列表和函数并从中生成一个BST。函数的类型是:'a list -> ('a * 'a -> bool) -> 'a tree
,但我遇到了一些问题,这里是我写的代码:
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;
我使用此功能获得的类型是:'a list -> ('b * 'c -> bool) -> 'd tree
当我尝试调用它时,如下面的makeBST [4, 3, 6, 7, 8, 2, 0, 1] (op <);
我收到以下错误:
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
代码有什么问题? 感谢
编辑:
我的代码的第二个版本:
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;
此代码生成了我想要的类型,但它是否正确?
答案 0 :(得分:2)
第一版代码存在两个问题:
fun makeBST _ _ = EMPTY
,所以这可能是您收到错误的原因是因为SML不知道EMPTY
应该是什么类型。虽然,既然你已经制作了第二个版本,我猜你已经抓住了它。但是,您的新代码仍然不正确。对此函数的任何调用的结果都是一个树,其中列表的第一个元素为根,两个EMPTY
个子元素。您正在比较左右子树,然后在正确的位置添加新值,但问题是您只返回该子树而不是整个树。你想要的是以下几点:
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;