(SML)从参考表格到正常插入trie?

时间:2013-02-13 01:01:44

标签: reference sml trie

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

(* 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)

1 个答案:

答案 0 :(得分:1)

如果您提供了EmptyNode来自的数据类型定义以及错误消息,那将会有所帮助。

这就是我假设数据类型定义适用于第一个函数:

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)尝试将t附加到Empty,其中t的类型为listEmpty的类型为'a trie {1}}”。您应该将其更改为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不是引用,因此您无法像这样分配它。相反,您应该使用let来引入局部变量。

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