0

我创建了这个破坏性插入尝试:

(* ins: char list * (char trie) ref list -> (char trie) ref list *)

 fun ins ([], t) = t@[ref Empty]
 | ins (x::xs, []) = [ref (Node (x, ins (xs, [])))]
 | ins (x::xs, h::tl) =
 case !h of
 Node (c, lis) =>
 if c = x then
 (h := Node (c, ins (xs, lis)); h::tl)
 else
 h::ins (x::xs, tl)
 | Empty => h::ins(x::xs, tl)

我试图让它在没有引用的情况下正常插入,但我不断收到错误。

(* ins: char list * (char trie) list -> (char trie) list *)

fun ins ([], t) = t@Empty
| ins (x::xs, []) = (Node (x, ins (xs, [])))
| ins (x::xs, h::tl) =
case h of
Node (c, lis) =>
if c = x then
(h = Node (c, ins (xs, lis)); h::tl)
else
h::ins (x::xs, tl)
| Empty = h::ins(x::xs, tl)
4

1 回答 1

1

如果您提供来自的数据类型定义和错误消息,将会有所Empty帮助Node

这就是我假设数据类型定义是针对第一个函数的:

datatype 'a trie = Empty | Node of 'a * 'a trie ref list

对于第二个:

datatype 'a trie = Empty | Node of 'a * 'a trie list

您的第二个功能有几个问题:

第一个子句 ( ns ([], t) = t@Empty) 尝试追加tEmpty,其中t有类型listEmpty有类型'a trie'。您应该将其更改ns ([], t) = t@[Empty]为匹配破坏性版本,以便进行类型检查。

case使用“胖箭头”而不是等号的子句。| Empty = h::ins(x::xs, tl)用这个替换| Empty => h::ins(x::xs, tl)

最后,这不是有效的 SML:

if c = x then
(h = Node (c, ins (xs, lis)); h::tl)

带括号的表达式是一个仅用于命令式代码的序列。该变量h不是引用,因此您不能像那样分配给它。相反,您应该使用 alet来引入局部变量。

if c = x then
       (let val h = Node (c, ins (xs, lis)) in  h::tl end)
else

这是最终的功能。这可以编译,但我没有仔细测试它,所以我不知道它是否还有另一个错误:

fun ins ([], t) = t@[Empty]
  | ins (x::xs, []) = [Node (x, ins (xs, []))]
  | ins (x::xs, h::tl) =
     case h of
        Node (c, lis) =>
            if c = x then
                   (let val h = Node (c, ins (xs, lis)) in  h::tl end)
            else
                h::ins (x::xs, tl)
      | Empty => h::ins(x::xs, tl)

    if c = x then
    (h = Node (c, ins (xs, lis)); h::tl)

    if c = x then
           (let val h = Node (c, ins (xs, lis)) in  h::tl end)
    else
于 2013-02-13T17:05:02.003 回答