SML列表删除

时间:2015-10-04 06:28:54

标签: sml smlnj ml

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

''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 个答案:

答案 0 :(得分:1)

这里有两个问题:

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