SML 列表删除

SML List Deletion

我正在尝试编写一个函数来从另一个列表中删除一个列表。

''a list -> ''a list -> ''a list

这是我目前的情况:

fun delete  _ [] = [] | 
    delete (h1::t1) (h2::t2) = 
     if h1=h2
     then t2
     else h2::delete (h1::t1) t2;

我正在使用 MoscowML,它给了我一个警告:模式匹配并不详尽错误。

以上功能的测试:

- delete [4,5] [1,2,3,4,5,6,7,8];
> val it = [1,2,3,5,6,7,8] : int list

期望的输出是:

> val it = [1,2,3,6,7,8] : int list

这里有两个问题:

1- 为什么解释器会引发警告:模式匹配不是详尽的错误

2- 如何使代码正常工作。

关于第一点,出现警告的原因是你没有检查所有可能发生的可能性。当前的函数 delete 只检查两种可能性:

-1 第二个列表是空列表(由模式覆盖:_ [] =

-2 两个列表都不为空(包含在第二个模式中:(h1::t1) (h2::t2) =

不过,还有第三种可能,即第一个列表为空列表。因此,以下输入将导致错误:delete [] [1,2,3,4,5,6]

关于第二点,如果确切的要求是从第二个列表中连续删除第一个列表中的元素,并且只删除一次,那么您的解决方案非常接近。 else 分支很好,只有 then 分支需要更多注意。 通过更正 then 分支,我得到以下结果:

delete [4,5] [1,2,3,4,5,6,7,8] = [1,2,3,6,7,8];
delete [5,4] [1,2,3,4,5,6,7,8] = [1,2,3,4,6,7,8];
delete [4,4,5] [1,2,3,4,5,6,7,8] = [1,2,3,5,6,7,8];
delete [4,5,6] [1,2,3,4,5,6,7,8] = [1,2,3,7,8];
delete [4,6,5] [1,2,3,4,5,6,7,8] = [1,2,3,5,7,8];
delete [4,6,5] [1,2,3,4,6,7,8,5] = [1,2,3,7,8];

但是,如果您想删除第一个列表中出现在第二个列表中的所有元素,而不考虑它们的顺序,那么您将需要重新考虑您的方法。

例如,如果您想要以下结果:

delete [4,6,5] [1,2,3,4,4,5,5,5,4,4,6,6,5,5,6,6,6,6,6,7,8,5] = [1,2,3,7,8];

那么你需要分两步来完成: 首先编写一个函数 del,给定一个元素将删除列表中所有出现的元素:fun del e l = ... 其实现实际上与您为 delete 提供的实现相同,只是您需要稍微更改 then 分支。

在你有了del之后,现在你可以实现函数delete,给定一个列表,它会删除第二个列表中所有出现该列表的地方。在这里您将使用先前定义的函数 del.