2017-05-27 50 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