1

我正在尝试编写一个函数来生成一个新列表,该列表包含给定列表而没有元素 x。

莫斯科 ML 表示在这场比赛中有些情况没有使用。

fun delete (x,list) = delete(x,[])
 |delete(x,(first::rest)) = if first = x then delete(x,rest) else first::delete(x,rest)
4

3 回答 3

4

以下是我在标准 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

没关系多等号。

于 2013-08-17T18:02:00.943 回答
1

那是因为您的第一个案例与任何列表匹配,所以永远不会使用第二个案例。
请记住,案例是按照编写顺序进行尝试的,而不是根据哪个是“最佳”匹配来选择的。

您还有一个无限递归的小问题

delete (x,list) = delete(x,[])

由于listwill 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)
于 2013-08-27T09:58:14.607 回答
1

当执行调用时delete,定义函数的模式(基本上)按顺序尝试。由于第一个模式已经匹配每个列表,因此永远不会到达第二个模式。这就是编译器抱怨的原因。

换句话说,您要么必须重新排序您的案例,或者更好地使它们不相交(例如,通过在第一个案例中替换为)list[]

额外提示:第一个案例的右侧似乎也有问题。这将始终进入无限递归。

于 2013-08-18T10:07:23.457 回答