Function 如何检查两个列表是否部分相同haskell
这是我的代码,我正在尝试检查一个列表是否可以与另一个相同。这是一场多米诺骨牌游戏,多米诺骨牌=(Int,Int)和棋盘=[Domino],并以左或右结束。我要检查是否有多米诺骨牌进入一块板,比如说多米诺骨牌Function 如何检查两个列表是否部分相同haskell,function,haskell,functional-programming,Function,Haskell,Functional Programming,这是我的代码,我正在尝试检查一个列表是否可以与另一个相同。这是一场多米诺骨牌游戏,多米诺骨牌=(Int,Int)和棋盘=[Domino],并以左或右结束。我要检查是否有多米诺骨牌进入一块板,比如说多米诺骨牌(2,3)进入板[(3,4)(5,6)]应该能够进入左端,因为(2,3)和(3,4)具有类似的元素。这是我的密码 goesP :: Domino -> Board -> End -> Bool goesP (h,t) [(h1,t1)] LeftEnd | h=
(2,3)
进入板[(3,4)(5,6)]
应该能够进入左端,因为(2,3)
和(3,4)
具有类似的元素。这是我的密码
goesP :: Domino -> Board -> End -> Bool
goesP (h,t) [(h1,t1)] LeftEnd
| h==h1 || t==h1 =True
| otherwise False
goesP (h,t) [(h1,t1)] RightEnd
| h==t1 || t==t1 = True
| otherwise False
用于线路板的模式匹配不完整。
[(h1,t1)]
图案将仅匹配具有一个元件的电路板(一对(h1,t1)
)
这与使用模式(h1,t1):[]
相同,即包含元素(h1,t1)
的列表(:
),后跟空列表[]
如果我们尝试使用您给出的示例运行代码,(2,3)
和[(3,4)、(5,6)]
(注意:列表元素之间需要逗号!),我们将得到以下结果:
goesP (2,3) [(3,4), (5,6)] LeftEnd
Haskell将尝试将这些参数与定义中的模式自上而下地匹配
它将首先检查以下模式:
goesP (h,t) [(h1,t1)] LeftEnd
通过将h
与2
,t
与3
和LeftEnd
与LeftEnd
进行“统一”,第一个和第三个参数将匹配,但第二个参数将无法匹配。参数[(3,4)、(5,6)]
是列表(3,4):(5,6):[]
的“语法糖”,而模式[(h1,t1)]
是列表(h1,t1):[]
的语法糖。我们可以将h1
与3
相统一,将t1
与4
相统一,但没有任何东西可以将(5,6)
与之统一
Haskell将继续讨论下一种可能性:
goesP (h,t) [(h1,t1)] RightEnd
第一个参数将匹配(与h
as2
和t
as3
),但第二个参数将失败,原因与前一个子句相同。第三个参数也将无法匹配,因为LeftEnd
和RightEnd
是不同的值(但这就是重点;)
Haskell将看到没有更多的可能性,因此程序将崩溃
要解决这个问题,您需要更改第二个参数的模式,以便正确处理具有多个Domino的板
LeftEnd
的情况非常简单,只需将一个元素的列表(h1,t1):[]
更改为至少一个元素的列表(h1,t1):\u
(我还在之后添加了额外的=
,否则):
RightEnd
的情况更难,因为我们希望与列表中的最后一个元素进行比较,但我们只能访问第一个元素。在这种情况下,我们可以保留检查单个元素列表的定义,但也可以添加另一个使用递归的定义:如果列表中有多个元素,请删除第一个元素并再次检查它。这样,任何非空列表最终都将被分解,直到它只有一个元素,您现有的模式可以使用它(同样,我添加了一个缺少的=
):
现在Haskell将[(3,4),(5,6)]
(这是(3,4):(5,6):[]
)与(h1,t1):[]
匹配。这将失败,因为列表的长度不同。然后,它将[(3,4)、(5,6)]
与\uuux:xs
匹配,这将成功地将xs
与(5,6):[]
统一起来。然后使用xs
再次运行该函数。这次(5:6):[]
将与(h1,t1):[]
统一,因此我们可以检查数字是否相等
另外,一个观察:goesP
实际上过于复杂。您正在使用“模式保护”在值True
和值False
之间进行选择;但是,图案防护装置也需要使用Bool
。换句话说,代码如下所示:
| h==h1 || t==h1 = True
| otherwise = False
可以理解为“创建Bool
值h==h1 | | t==h1
;如果为True
,则返回True
。如果为False
,则返回False
”
显然这是多余的:我们只需返回值h==h1 | | t==h1
:
goesP (h,t) ((h1,t1):_) LeftEnd = h==h1 || t==h1
goesP (h,t) [(h1,t1)] RightEnd = h==h1 || t==h1
goesP (h, t) (_:xs) RightEnd = goesP (h, t) xs RightEnd
更新:修复了我的右端代码请格式化您提供的代码片段(它应该看起来像这样
)。目前,它几乎无法阅读。您可以使用反勾号或四个缩进空格来获得此效果。谷歌搜索“markdown”以了解有关其语法规则的更多信息。@AndrewThaddeusMartin或在编辑时只需单击help
按钮,它将显示所有格式语法。此外,我们更喜欢此网站的正确语法和拼写。我现在编辑了这篇文章,但请确保你自己在将来的问题上做对了。至于这一点,我们仍然不清楚你说的是什么,“一个目的是左还是右”。更重要的是,你的问题是什么?你给了我们一些代码,这是一个开始。但是在你所写的东西和将要编译和工作的东西之间还有很长的路要走。否则=False
添加一个=
| h==h1 || t==h1 = True
| otherwise = False
goesP (h,t) ((h1,t1):_) LeftEnd = h==h1 || t==h1
goesP (h,t) [(h1,t1)] RightEnd = h==h1 || t==h1
goesP (h, t) (_:xs) RightEnd = goesP (h, t) xs RightEnd