我正在尝试编写一个函数来生成一个新列表,该列表包含给定列表而没有元素 x。
莫斯科 ML 表示在这场比赛中有些情况没有使用。
fun delete (x,list) = delete(x,[])
|delete(x,(first::rest)) = if first = x then delete(x,rest) else first::delete(x,rest)
以下是我在标准 ML 上的做法::
fun delete (item, list) =
case list of
[]=>[]
| xs::ys => if item = xs then delete(item,ys)
else xs::delete(item,ys)
不使用案例:
fun delete (item, list) = List.filter(fn x => x <> item) list
没关系多等号。
那是因为您的第一个案例与任何列表匹配,所以永远不会使用第二个案例。
请记住,案例是按照编写顺序进行尝试的,而不是根据哪个是“最佳”匹配来选择的。
您还有一个无限递归的小问题
delete (x,list) = delete(x,[])
由于list
will match []
,它将永远递归。
如果您从空列表中删除某些内容,则结果应该是空列表。
你可以做两件事之一。
要么先移动非空案例:
fun delete (x, y:ys) = if y = x then delete(x, ys) else y::delete(x, ys)
| delete (x, list) = []
或者,更常见的是,使第一种情况只匹配空列表:
fun delete (x, []) = []
| delete (x, y:ys) = if y = x then delete(x, ys) else y::delete(x, ys)
当执行调用时delete
,定义函数的模式(基本上)按顺序尝试。由于第一个模式已经匹配每个列表,因此永远不会到达第二个模式。这就是编译器抱怨的原因。
换句话说,您要么必须重新排序您的案例,或者更好地使它们不相交(例如,通过在第一个案例中替换为)list
。[]
额外提示:第一个案例的右侧似乎也有问题。这将始终进入无限递归。