我为尝试创建了这种破坏性插入:
(* 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)
答案 0 :(得分: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
)尝试将t
附加到Empty
,其中t
的类型为list
但Empty
的类型为'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