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
.
我正在尝试编写一个函数来从另一个列表中删除一个列表。
''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
.