首先,讓我注意你應該包含你得到的錯誤信息。你也應該向我們展示一些樣本輸出和樣本輸入。
總之:您目前appd
不處理空列表,所以你需要通過添加案件爲開始:
appd _ [] = []
appd [] bs = snd <$> bs -- you can decide to use [] instead
appd (a:e) ((c,b):bs)
| a == c && bs /= [] = b:appd(a:e) bs
| a /= c && bs /= [] = appd (a:e) bs
| a /= c && bs == [] = appd e ((c,b):bs)
| otherwise = b:appd e ((c,b):bs)
現在你的函數可以使用您所提供的輸入,但我不知道它返回的結果,你的願望:
*Main> appd [1,2,3] [(1,2),(6,5),(3,5)]
[2,5,5]
此外,我已經清理你的代碼一點點,有一個明確的類型簽名註釋你的函數:
appd :: (Eq a, Eq b) => [a] -> [(a,b)] -> [b]
appd [] bs = snd <$> bs
appd _ [] = []
appd [email protected](a:ass) [email protected]((c,b):bss)
| a == c && bss /= [] = b : appd as bss
| a /= c && bss /= [] = appd as bss
| a /= c && bss == [] = appd ass bs
| otherwise = b : appd ass bs
此外,您可以用更簡單的,非遞歸執行情況得到同樣的結果如上:
appd :: (Eq a, Eq b) => [a] -> [(a,b)] -> [b]
appd as bs = snd <$> filter (\(a,_) -> a `elem` as) bs
,或者如果你喜歡point free(又名tacit):
appd :: (Eq a, Eq b) => [a] -> [(a,b)] -> [b]
appd as = (snd <$>) . filter ((`elem` as) . fst)
注:<$>
是fmap
的別名,這反過來又對列表中使用時表現酷似map
。
無法重現:在我的測試中,它確實返回與'1','2'和'3'配對的結果;例如'appd [1,2,3] [(1,2),(6,5),(3,5)]'似乎可以正確地從'(1,2)'返回'2',並且碰撞前從'(3,5)'發出'5'。如果我在末尾添加了一個「(2,4)」,它會在崩潰之前返回「4」。但是,這個函數是非常局部的 - 它幾乎每個輸入都會崩潰。也許如果你解決了這個問題(試着用'-fwarn-incomplete-patterns'檢查GHC的輸出),它會表現得更像你想要的。 –
回答你的問題的方法是把你已經隔離的測試用例('appd [1,2,3] [(1,2),(6,5),(3,5)]')和在你的腦海裏,在紙上或者用調試器仔細執行它,並且認真思考。 – jberryman
我試過了,但是我看不到錯誤 – dreamPr