【问题标题】:Understanding Haskell's filter了解 Haskell 的过滤器
【发布时间】:2011-02-03 19:51:06
【问题描述】:

我知道 Haskell 的过滤器是一个高阶函数(意味着一个函数将另一个函数作为参数),它通过一个列表检查哪个元素满足某个布尔条件。

我不太明白它的定义:

filter:: (a->Bool)->[a]->[a]
filter p [] = []
filter p (x:y) | p x = x:filter p y
               | otherwise = filter p y

我知道如果我将一个空列表传递给函数,它只会返回一个空列表,但我如何阅读最后两行?

【问题讨论】:

  • @Justice:我想知道重新格式化是否有效。也许OP真的被奇怪的布局弄糊涂了?

标签: list haskell filter


【解决方案1】:

它使用guards,如果您来自具有 C 风格语法的语言,则它与switch 结构有点相似。

最后一个模式是:如果函数p 使用参数x 计算结果为true,则返回列表的头部和过滤后的列表尾部。否则只返回列表的过滤尾部。

你也可以这样重写:

filter p (x:y) = if (  p x ) then
                     x:filter p y
                 else
                     filter p y

【讨论】:

  • 还有otherwise在前奏中被定义为True
  • 你好 Yacoby 我喜欢你的过滤器实现,不幸的是,在使用它时非常简单,例如 filter (>7) [1,5,7,8.9,11,2,1] 我收到一个错误:[ 8,9,11*** 例外:db.hs:(45,1)-(48,13):函数过滤器中的非详尽模式...如何解决?
【解决方案2】:

考虑description of filter in the docs

filter,应用于谓词和列表,返回满足谓词的那些元素的列表;

filter p xs = [x | x <- xs, p x]

为了向不懂列表推导的人解释,你可能会说filter 有三种情况:

  1. (最简单的情况)当要过滤的列表为空时,结果也为空
  2. 当要过滤的列表的头部满足谓词时,它就是结果的一部分
  3. 否则,跳过头部并过滤列表的其余部分

这些案例与您问题中定义的最后三行一一对应。

细微的接触可以使定义更惯用,因此更易于阅读:

filter _ []      = []
filter p (x:xs)
  | p x          = x : filter p xs
  | otherwise    =     filter p xs

对于一个空列表,谓词可以是任何东西,下划线明确表明它在这种情况下并不重要。

而不是匹配(x:y),使用(x:xs)——想想:“ex and exes”——强调你将一个列表分成它的头部(a类型)和尾部([a]类型,iea 的列表)。

最后,排列对filter 的递归调用很容易让读者看到后一种情况省略了x

【讨论】:

    猜你喜欢
    • 2013-08-03
    • 2020-07-08
    • 2011-07-27
    • 2013-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多