SML - 为什么我的代码返回一个奇怪的引用?

时间:2015-03-22 05:29:30

标签: reference linked-list sml

我正在尝试编写一个使用引用的函数,并在插入值时破坏性地更新已排序的链表。 我的代码如下:

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

2 个答案:

答案 0 :(得分:2)

这意味着您的代码有问题,并且返回了一个循环列表,其中ref(RCons(4, ...))的尾部实际上是ref(RCons(4, ...))实际上是comp

说明:

  1. 您无需将toInsertif C then true else false传递给内部函数,它们已经在范围内。
  2. C与仅撰写t * t -> order
  3. 相同
  4. 在SML中,您通常使用类型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'
  5. 代码中大约70%的括号都是多余的。

  6. 您通常不希望在ML中使用这样的数据结构。

  7. 如果你绝对必须,我会写下代码:

    {{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)))