2015-10-26 88 views
0

我有這樣的代碼:哈斯克爾遞歸

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) 

它循環throught兩個列表像[1,2,3][(1,2),(6,5),(3,5)]並採取第一個列表的第一個元素,並將其與其他列表中的每個元組的第一個元素,如果它們相等,則保存該元組的第二個元素。它工作正常,但如果我拿第一個列表的第二個元素,在這種情況下,比較不起作用2

例如,如果我有像[1,2,3][(1,2),(6,5),(3,5)]列表,然後函數從第一個列表需要1和比較1,然後6,然後3,這工作,但它沒有考慮第一個列表的第二個元素 - 2和不會再做比較。怎麼了?

+0

無法重現:在我的測試中,它確實返回與'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的輸出),它會表現得更像你想要的。 –

+0

回答你的問題的方法是把你已經隔離的測試用例('appd [1,2,3] [(1,2),(6,5),(3,5)]')和在你的腦海裏,在紙上或者用調試器仔細執行它,並且認真思考。 – jberryman

+0

我試過了,但是我看不到錯誤 – dreamPr

回答

1

首先,讓我注意你應該包含你得到的錯誤信息。你也應該向我們展示一些樣本輸出和樣本輸入。


總之:您目前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

https://www.haskell.org/hoogle/?hoogle=%3C %24%3E –

+0

啊,是的,我忘了提什麼'<$>'。 –

+0

非常感謝你!不幸的是,我的功能仍然無法正常工作,但你的建議更簡單的實施工作正常。這裏是樣本輸入:[1,2,3,4] [(1,5),(3,8),(5,5),(4,3),(2,9)]輸出:[5, 9,8,3] – dreamPr