2017-05-27 55 views
1

給出(無家庭作業):哈斯克爾遞歸查找功能和Data.Foldable找到解釋

first' :: (a -> Bool) -> [a] -> Maybe a 
-- Finds the first element of a list that satisfies a given condition. 
  1. 我得到這個語句後丟失: if p x then Just x else Nothing) 如何繼續使它遞歸?

  2. 我發現這一點:

    -- | The 'find' function takes a predicate and a structure and returns 
    -- the leftmost element of the structure matching the predicate, or 
    -- 'Nothing' if there is no such element. 
    find :: Foldable t => (a -> Bool) -> t a -> Maybe a 
    find p = getFirst . foldMap (\ x -> First (if p x then Just x else Nothing)) 
    

但我不明白這個部分:getFirst . foldMap (\ x -> First (

有人能解釋一下這個說法?

回答

2

如果您正在學習Haskell,我建議您暫時忘記FoldableFirst,因爲這些涉及比實現first'所需更高級的主題。

作爲一個提示,儘量制定出如下所示的簡單遞歸定義:在空列表

  • 什麼應該是先滿足p

    -- Finds the first element of a list that satisfies a given condition. 
    first' :: (a -> Bool) -> [a] -> Maybe a 
    first' p [] = ... 
    first' p (x:xs) = ... 
        where 
        -- the first in the tail xs 
        rec = first' p xs 
    

    想想吧?

  • 假設rec在尾單xs第一令人滿意p,你會怎樣表達的完整列表x:xs第一令人滿意p?你可以使用if-then-else。
+0

謝謝您的明確解釋,但我仍然有我的原始問題: 在「正常」遞歸函數中,只要條件未滿足(result = Nothing),則迭代;或者如果條件滿足,結果=只是x)我們停下來。 這裏我需要三個條件:沒有,只要x,繼續迭代。 – Atir

+0

謝謝您的明確解釋,但我仍然有我的原始問題: 這是Maybe語句讓我困惑。 在「正常」遞歸函數中,只要條件不滿足(result = Nothing),或者條件滿足(result = Just x),我們就停止。 這裏我需要三個條件:Nothing,只需x並繼續迭代。 我該如何克服這個困難? – Atir

+0

@Atir如果列表是空的,你知道沒有滿足'p'的值,所以你可以返回Nothing。否則,你可以檢查'p x':它持有,你可以返回'只需x',否則,你會與列表的其餘部分遞歸。 – chi

2

但我不明白這一節:getFirst。 。foldMap(\ X - >首先(

首先,讓我們來看看有點在First,例如,在LYAH這是一個,這樣的定義:

newtype First a = First { getFirst :: Maybe a } 
    deriving (Eq, Ord, Read, Show) 

instance Monoid (First a) where 
    mempty = First Nothing 
    First (Just x) `mappend` _ = First (Just x) 
    First Nothing `mappend` x = x 

直觀上,這意味着:

  • 「空」元件是Nothing

  • First「追加」的兩個元件是其中所述第一JustFirst如果有一個,否則First Nothing

因此,正如其名稱所暗示的那樣,它是一個「記錄」它遇到的第一個Just的monoid。


如果你看一下foldMap,這毫不奇怪,在執行可摺疊的摺疊一切的映射版本的組合。直觀地說,如果摺疊包含一些Just,則foldMap的結果是First,例如Just;否則,它是First Nothing


現在,你想從這個First值提取到一個Maybe。這是getFirst所做的。

整條生產線由foldMap組成getFirst