我正在尝试编写一个使用引用的函数,并在插入值时破坏性地更新已排序的链表。 我的代码如下:
Control.Print.printDepth := 100;
datatype 'a rlist = Empty | RCons of 'a * (('a rlist) ref);
fun insert(comp: (('a * 'a) -> bool), toInsert: 'a, lst: (('a rlist) ref)): unit =
let
val r = ref Empty;
fun insert' comp toInsert lst =
case !lst of
Empty => r := (RCons(toInsert, ref Empty))
| RCons(x, L) => if comp(toInsert, x) then r := (RCons(toInsert, lst))
else ((insert(comp,toInsert,L)) ; (r := (RCons(x, L))));
in
insert' comp toInsert lst ; lst := !r
end;
val nodes = ref (RCons(1, ref (RCons(2, ref (RCons(3, ref (RCons(5, ref Empty))))))));
val _ = insert((fn (x,y) => if x <= y then true else false), 4, nodes);
!nodes;
!nodes返回
val it = RCons (1,ref (RCons (2,ref (RCons (3,ref (RCons (4,%1)) as %1)))))
: int rlist
什么时候应该返回
val it = RCons (1,ref (RCons (2,ref (RCons (3,ref (RCons (4, ref (RCons(5, ref Empty))))))))
: int rlist
答案 0 :(得分:2)
这意味着您的代码有问题,并且返回了一个循环列表,其中ref(RCons(4, ...))
的尾部实际上是ref(RCons(4, ...))
实际上是comp
。
说明:
toInsert
和if C then true else false
传递给内部函数,它们已经在范围内。C
与仅撰写t * t -> order
。Int.compare
的比较函数,它们是在库中预定义的,例如, datatype 'a rlist' = Empty | Cons of 'a * 'a rlist
withtype 'a rlist = 'a rlist' ref
fun insert compare x l =
case !l of
Empty => l := Cons(x, ref Empty)
| Cons(y, l') =>
case compare(x, y) of
LESS => l := Cons(x, ref(!l))
| EQUAL => () (* or whatever else you want to do in this case *)
| GREATER => insert compare x l'
。代码中大约70%的括号都是多余的。
您通常不希望在ML中使用这样的数据结构。
如果你绝对必须,我会写下代码:
{{1}}
答案 1 :(得分:0)
更改
| RCons(x, L) => if comp(toInsert, x) then r := (RCons(toInsert, lst))
到
| RCons(x, L) => if comp(toInsert, x) then r := (RCons(toInsert, ref(!lst)))