【问题标题】:Parameters in anonymous function匿名函数中的参数
【发布时间】:2021-02-19 14:31:38
【问题描述】:

我一直在练习匿名函数并得到以下结果:

takeWhile' :: (a -> Bool) -> [a] -> [a]
takeWhile' f xs = foldl (\x y z -> if (f x) && z then x : y else y) xs [] True

这基本上是对 Haskell 中的 takeWhile 函数的重写。

对于那些不知道的人,takeWhile 函数接受一个列表和一个函数,并返回一个新列表,其中包含原始列表中满足该函数的每个元素,直到其中一个给出 false。

从我的角度来看,一切似乎都是正确的,我有 3 个参数 xy 和 z 可以在我的匿名函数中使用,x 是数字列表,y 是我将插入每个元素的空列表和 z基本上是一个去抖动器,所以如果其中一个元素不符合要求,我们就不再插入。

然而 Haskell 给了我以下错误:

"Occurs check: cannot construct the infinite type: a ~ Bool -> [a]"

知道为什么吗?

【问题讨论】:

  • 除非您打算将xs 用作函数列表并提供一个函数作为初始值,否则匿名函数只能接受两个参数。
  • 我认为这需要是foldr,因为这是折叠应用程序可以简化为 lambda 应用程序的唯一方法,允许提供第三个参数。
  • foldl 有两个参数:累加器x 和元素yz 在这里做什么?

标签: haskell lambda anonymous-function


【解决方案1】:

fold 中的 fold 函数将累加器 x 和元素 y 作为参数。所以没有 z 被传递。

但即使以某种方式可行,仍然存在其他问题。 x 是这里的累加器,所以是一个列表,这意味着x : y 没有意义,因为(:) :: a -> [a] -> [a] 接受一个元素和一个列表,并构造一个新列表。

但是,您可以轻松地使用foldr 来实现takeWhile 函数。确实:

takeWhile' p = foldr (\x -> if p x then (x :) else const []) []

因此,我们在这里检查谓词是否成立,如果是这样,我们在累加器前面加上x。如果不是,我们返回[],不管累加器的值是多少。

由于foldr 的懒惰,它不会在元素未能通过累加器后查找元素,因为const []ingore 累加器的值。

【讨论】:

    猜你喜欢
    • 2020-01-03
    • 2011-03-02
    • 1970-01-01
    • 1970-01-01
    • 2019-02-10
    • 1970-01-01
    • 1970-01-01
    • 2014-05-22
    • 1970-01-01
    相关资源
    最近更新 更多