2014-08-30 26 views
1

我在做自我練習,並且想知道是否有一種方法可以在列表中找到左側的第一個項目,只需使用foldr即可滿足特定條件?我希望遞歸在發現第一個項目時停止(我知道我可以使用take進行組合),但我很想知道是否可以使用foldr獲取符合條件的第一個使用foldr的商品

firstFind (\x -> x > 1000) [] xs 
+0

從一開始第一個項目或列表的末尾。? – soulcheck 2014-08-30 12:23:04

+0

如果可能的話 – 2014-08-30 12:30:35

+1

*提示*:使用摺疊實現'filter',然後使用'head'(或者如果它對你很重要,則不會在空列表中出現底部) – Carsten 2014-08-30 12:34:02

回答

8

問題:找到fb

firstFind :: (a -> Bool) -> [a] -> Maybe a 
firstFind p list = foldr f b list 
    where f = ??? 
     b = ??? 

我們希望:

firstFind p [] = Nothing 

但我們也有

firstFind p [] 
= def. firstFind 
foldr f b [] 
= def. foldr 
b 

從中我們看到b必須。

此外,採取list = x:xs

firstFind p list 
= def. firstFind 
foldr f b (x:xs) 
= def. foldr 
f x (foldr f b xs) 
= def. firstFind 
f x (firstFind p xs) 

現在,我們只需要找到f使這一選擇的第一場比賽。

回想一下,f可以依賴於p。當p x爲真時f應該返回什麼?相反的情況是什麼?

where -- f :: a -> Maybe a -> Maybe a 
     f x y = ??? 

(注:以上我寫的類型簽名f爲清楚起見,但你沒有把它列入你的代碼,如果添加它,註釋掉,你會跳成類型變量的困惑:這a是不一樣的afindFirst,因爲它是在本地推廣 - 因爲你是剛開始,忽略它,只需刪除它的時刻是)

+0

只是一個小問題:如果你給一個明確的類型簽名,單態限制不適用,所以添加它應該沒問題。 – bennofs 2014-08-30 21:04:48

+0

@bennofs我不知道我爲什麼寫這個。糾正。 – chi 2014-08-30 21:10:21

相關問題