2014-10-19 119 views
0

這是我的代碼即時通訊嘗試檢查列表是否可以與其他列表相同。這是一個多米諾骨牌遊戲,一個Domino=(Int,Int)和一個Board = [Domino]和結束左或右。我要檢查是否有任何多米諾骨牌進入董事會說,例如多米諾骨牌(2,3)進入[(3,4)(5,6)]應該能夠走到左端,因爲(2,3)(3,4)有一個相似的元素。這是我的代碼如何檢查兩個列表是否部分相同haskell

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 
+1

請格式化的,你提供的代碼片段(它看起來應該'喜歡this' )。目前,這幾乎是不可讀的。您可以使用反引號或四個縮進空格來獲得此效果。谷歌的「降價」,以瞭解更多關於它的語法規則。 – 2014-10-19 23:04:01

+2

@AndrewThaddeusMartin編輯時只需點擊'help'按鈕,就會顯示所有的格式化語法。 – bheklilr 2014-10-19 23:05:07

+0

此外,我們更喜歡在本網站上正確的語法和拼寫。我現在編輯了這篇文章,但是請確保你自己爲將來的問題做好準備。至於這一點,目前還不清楚你在談論什麼,「結局是左還是右」。 – leftaroundabout 2014-10-19 23:10:57

回答

1

您用於電路板的模式匹配不完整。 [(h1,t1)]模式將只有匹配板與一個元素(一對(h1,t1))。

這與使用圖案(h1,t1):[]相同,即。包含元素(h1,t1)後跟空列表[]的列表(:)。

如果我們試圖用你給,(2,3)[(3,4), (5,6)]實例運行代碼(注意:您需要的列表元素之間的逗號!),我們將得到以下內容:

goesP (2,3) [(3,4), (5,6)] LeftEnd 

哈斯克爾將嘗試將這些論點與自定義中的模式從上到下進行匹配。與2

goesP (h,t) [(h1,t1)] LeftEnd 

的第一和第三個參數匹配,通過「統一」 ht3LeftEndLeftEnd,但第二個將不匹配:

它會檢查以下模式第一。參數[(3,4), (5,6)]對於列表(3,4):(5,6):[]是'語法糖',而[(h1,t1)]是對於列表(h1,t1):[]的句法糖。我們可以統一h13t14,但沒有什麼可以統一(5,6)與。

哈斯克爾將移動到下一個可能性:

goesP (h,t) [(h1,t1)] RightEnd 

的第一個參數匹配(與h2t3),但第二個參數將失敗出於同樣的原因如前項。第三個參數也將無法匹配,因爲LeftEndRightEnd是不同的值(但這就是要點;))。

Haskell然後會看到沒有更多的可能性,所以程序會崩潰。

要解決此問題,您需要更改第二個參數的模式,以便正確處理具有多個Domino的Board。

LeftEnd的情況下是很容易的,只是一個元素(h1,t1):[]列表更改爲至少一個元素(h1,t1):_(我還添加了額外的=otherwise後)的列表:

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 

現在哈斯克爾將匹配[(3,4), (5,6)](這是糖的(3,4):(5,6):[])對(h1,t1):[]。這將失敗,因爲列表的長度不同。然後它將匹配[(3,4), (5,6)]_:xs,這將成功,統一xs(5,6):[]。然後我們再次運行該功能,使用xs。這一次(5:6):[](h1,t1):[]統一,所以我們可以檢查數字是否相等。

此外,觀察:goesP實際上過於複雜。您正在使用「花樣警衛」在值True和值False之間進行選擇;然而,花紋警衛要求 a Bool與之合作。換句話說,這樣的代碼:

| h==h1 || t==h1 = True 
| otherwise  = False 

可以理解爲說「創建Boolh==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 

更新:修正了我的RightEnd代碼