尝试访问列表尾部时出现匹配冗余错误

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));