尝试访问列表尾部时出现匹配冗余错误
Getting a match redundant error when trying to access the tail of a list
我正在用 sml 编写一个函数,它检查初始列表是否包含在第二个列表的任何方面。这是我目前所拥有的:
fun contains l1 [] = false
| contains l1 (hd::tl) = contains l1 tl
| contains l1 l2 = starts l1 l2;
编辑:这是我的启动函数(检查列表 l1 是否启动 l2):
fun starts [] l2 = true
| starts l [] = false
| starts (h1::t1) (h2::t2) = if((h1=h2) andalso (starts t1 t2)) then true else false;
然而它给了我错误:
stdIn:21.3-21.97 Error: match redundant
谁能帮我弄清楚为什么?
谢谢
错误的原因是因为这一行:
contains l1 l2 = starts l1 l2;
与上一行没有什么不同:
contains l1 (hd::tl) = contains l1 tl
两行表示相同的匹配模式。你可以这样写:contains l1 (l2 as (hd::tl)) = contains l1 tl
这会使解释器感到困惑,因为您告诉它在这种模式的情况下:contains l1 l2
,做两件不同的事情,即:
starts l1 l2;
和
contains l1 tl
获得解决方案的方法是删除 contains
的最后一行,因为它是多余的。
在第二行中,您的目的是现在循环遍历第二个列表的初始元素,直到到达第二个列表的 'current element' 与第一个列表的第一个元素匹配的点。 如果是这种情况,则调用start
else继续循环。
考虑 val first_list = [2,3,4]
和 val second_list = [1,2,2,2,2,3,4,5,6]
所以第二行中的 contains
必须首先遍历 second_list
的元素以查看第一个元素是否匹配。如果它们匹配,则调用开始。所以你得到以下细分:
2=1? => false
因此循环到第二个元素
2=2? => true
因此调用 start
以查看我们是否有从那时起的匹配列表。
由于 start
在检查 3=2? => false
时会 return 为假,您现在必须继续在 contains
中循环并重复此过程。它必须循环直到到达 second_list
中的最终 2
。此时对比会是这样:
2=2? => true
因此调用 start
来检查连续元素是否匹配。
start
现在将计算为 true
,如下所示:
3=3? => true
4=4? => true
5=5? => true
--> 此时 start
将 return 为真,这也应该是 contains 的 return 值。如果 start
在任何一点 returns false
那么你需要继续循环。
最终,您将 first_list
与 []
进行模式匹配,这将被您的第一行捕获。
注意:
start
是正确的,但要避免这种模式:if a=b then true else false
,而只写 a=b
:
所以像这样重写 start
的最后一行:
| starts (h1::t1) (h2::t2) = ((h1=h2) andalso (starts t1 t2));
我正在用 sml 编写一个函数,它检查初始列表是否包含在第二个列表的任何方面。这是我目前所拥有的:
fun contains l1 [] = false
| contains l1 (hd::tl) = contains l1 tl
| contains l1 l2 = starts l1 l2;
编辑:这是我的启动函数(检查列表 l1 是否启动 l2):
fun starts [] l2 = true
| starts l [] = false
| starts (h1::t1) (h2::t2) = if((h1=h2) andalso (starts t1 t2)) then true else false;
然而它给了我错误:
stdIn:21.3-21.97 Error: match redundant
谁能帮我弄清楚为什么?
谢谢
错误的原因是因为这一行:
contains l1 l2 = starts l1 l2;
与上一行没有什么不同:
contains l1 (hd::tl) = contains l1 tl
两行表示相同的匹配模式。你可以这样写:contains l1 (l2 as (hd::tl)) = contains l1 tl
这会使解释器感到困惑,因为您告诉它在这种模式的情况下:contains l1 l2
,做两件不同的事情,即:
starts l1 l2;
和
contains l1 tl
获得解决方案的方法是删除 contains
的最后一行,因为它是多余的。
在第二行中,您的目的是现在循环遍历第二个列表的初始元素,直到到达第二个列表的 'current element' 与第一个列表的第一个元素匹配的点。 如果是这种情况,则调用start
else继续循环。
考虑 val first_list = [2,3,4]
和 val second_list = [1,2,2,2,2,3,4,5,6]
所以第二行中的 contains
必须首先遍历 second_list
的元素以查看第一个元素是否匹配。如果它们匹配,则调用开始。所以你得到以下细分:
2=1? => false
因此循环到第二个元素
2=2? => true
因此调用 start
以查看我们是否有从那时起的匹配列表。
由于 start
在检查 3=2? => false
时会 return 为假,您现在必须继续在 contains
中循环并重复此过程。它必须循环直到到达 second_list
中的最终 2
。此时对比会是这样:
2=2? => true
因此调用 start
来检查连续元素是否匹配。
start
现在将计算为 true
,如下所示:
3=3? => true
4=4? => true
5=5? => true
--> 此时 start
将 return 为真,这也应该是 contains 的 return 值。如果 start
在任何一点 returns false
那么你需要继续循环。
最终,您将 first_list
与 []
进行模式匹配,这将被您的第一行捕获。
注意:
start
是正确的,但要避免这种模式:if a=b then true else false
,而只写 a=b
:
所以像这样重写 start
的最后一行:
| starts (h1::t1) (h2::t2) = ((h1=h2) andalso (starts t1 t2));