[英]How to check if two lists are partially identical haskell
這是我的代碼,我試圖檢查一個列表是否可以與另一個列表完全相同。 這是一個多米諾骨牌游戲,一個Domino=(Int,Int)
和一個Board = [Domino]
,終點是左或右。 我要檢查是否有多米諾骨牌進入棋盤,例如可以將多米諾骨牌(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)
)的Board。
這與使用模式(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
與LeftEnd
,但是第二個參數將不匹配。 參數[(3,4), (5,6)]
是列表(3,4):(5,6):[]
'語法糖',而模式[(h1,t1)]
是句法的列表(h1,t1):[]
糖。 我們可以用3
統一h1
,用4
統一t1
,但是沒有什么可以統一(5,6)
。
Haskell將繼續進行下一個可能性:
goesP (h,t) [(h1,t1)] RightEnd
第一個參數將匹配( h
為2
且t
為3
),但是第二個參數由於與上一個子句相同的原因而失敗。 第三個參數也將不匹配,因為LeftEnd
和RightEnd
是不同的值(但這就是要點;))。
然后,Haskell將看到沒有更多可能性,因此該程序將崩潰。
要解決此問題,您需要更改第二個參數的模式,以便正確處理具有多個Domino的Board。
LeftEnd
情況非常簡單,只需將一個元素(h1,t1):[]
的列表更改為至少一個元素(h1,t1):_
( otherwise
我還添加了extra =
):
goesP (h,t) ((h1,t1):_) LeftEnd
| h==h1 || t==h1 = True
| otherwise = False
對於此案RightEnd
是很難的,因為我們想用列表的最后一個元素進行比較,但我們只能夠獲得第一 。 在這種情況下,我們可以保留檢查單元素列表的定義,但也可以添加使用遞歸的另一個定義:如果列表包含多個元素,請刪除第一個元素並再次檢查。 這樣,任何非空列表都將最終分解,直到只有一個元素可以使用您現有的模式(同樣,我添加了一個丟失的=
):
goesP (h,t) [(h1,t1)] RightEnd
| h==h1 || t==h1 = True
| otherwise = False
goesP (h, t) (_:xs) RightEnd = goesP (h, t) xs RightEnd
現在Haskell將[(3,4), (5,6)]
( (3,4):(5,6):[]
糖與(h1,t1):[]
匹配(h1,t1):[]
。 這將失敗,因為列表的長度不同。 然后它將[(3,4), (5,6)]
與_: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
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
更新:修復了我的RightEnd代碼
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.