我正在sml中编写一个函数,它检查初始列表是否包含在第二个列表的任何方面。以下是我到目前为止的情况:
fun starts [] l2 = true
| starts l [] = false
| starts (h1::t1) (h2::t2) = if((h1=h2) andalso (starts t1 t2)) then true else false;
编辑:这是我的启动功能(检查列表l1是否启动l2):
$_products = Mage::getModel('catalog/product')->getCollection();
然而,它给了我错误:
stdIn:21.3-21.97错误:匹配冗余
任何人都可以帮我找出原因吗?
由于
答案 0 :(得分:1)
错误的原因是因为这一行:
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
的最后一行,因为它是多余的。
在第二行中,您的目的是循环遍历第二个列表的初始元素,直到达到“当前元素”的位置。第二个列表的第一个元素匹配第一个列表的第一个元素。 如果这种情况,请调用start
其他继续循环播放。
考虑val first_list = [2,3,4]
和val second_list = [1,2,2,2,2,3,4,5,6]
因此,第二行中的contains
必须首先遍历second_list
的元素,以查看第一个元素是否匹配。如果匹配则调用start。所以你得到了以下细分:
2=1? => false
因此循环到第二个元素
2=2? => true
因此调用start
以查看从那时起我们是否有匹配的列表。
由于start
在检查3=2? => false
时将返回false,您现在必须继续在contains
中循环并重复此过程。它必须循环,直到它到达2
中的最终second_list
。此时的比较将是这样的:
2=2? => true
因此调用start
来检查连续元素是否匹配。
start
现在将评估为true
,如下所示:
3=3? => true
4=4? => true
5=5? => true
- >此时start
将返回true,这也应该是contains的返回值。如果start
在任何时候返回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));