【发布时间】:2013-08-19 22:39:51
【问题描述】:
我正在尝试编写一个函数来生成一个包含给定列表但不包含元素 x 的新列表。
Moscow ML 表示本场比赛中没有使用某些情况。
fun delete (x,list) = delete(x,[])
|delete(x,(first::rest)) = if first = x then delete(x,rest) else first::delete(x,rest)
【问题讨论】:
我正在尝试编写一个函数来生成一个包含给定列表但不包含元素 x 的新列表。
Moscow ML 表示本场比赛中没有使用某些情况。
fun delete (x,list) = delete(x,[])
|delete(x,(first::rest)) = if first = x then delete(x,rest) else first::delete(x,rest)
【问题讨论】:
那是因为您的第一个 case 匹配 any 列表,所以永远不会使用第二个 case。
请记住,案例是按照编写顺序进行审理的,而不是根据哪个是“最佳”匹配来选择的。
你还有一个无限递归的小问题
delete (x,list) = delete(x,[])
由于list 将匹配[],它将永远递归。
如果从空列表中删除某些内容,结果应该是空列表。
你可以做两件事之一。
要么先移动非空的情况:
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 (x, list) = [] 到底是干什么用的?我无法以这种递归方式理解这部分的作用。谢谢
[],或者_。
当调用delete 时,定义函数的模式(基本上)按顺序尝试。由于第一个模式已经匹配每个列表,因此永远不会到达第二个模式。这就是编译器抱怨的原因。
换句话说,您要么必须重新排序您的案例,或者更好地使它们不相交(例如,在第一个案例中将 list 替换为 [])。
额外提示:第一种情况的右侧似乎也有误。这将始终进入无限递归。
【讨论】:
这是我在标准 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
不要介意多等号。
【讨论】: