【发布时间】:2020-11-28 07:09:16
【问题描述】:
我正在学习 Haskell,我发现了一个使用 foldr 的有趣的 init 实现。但是,我很难理解它是如何工作的。
init' xs = foldr f (const []) xs id
where f x g h = h $ g (x:)
假设我有一个[1,2,3] 的输入,那么它会变成
f 1 (f 2 ( f 3 (const []))) id
我将这些参数替换为f,最里面的参数变为h $ (const []) (1:),即h []。然而,当我想进一步减少表达时,我发现很难掌握。下一个变成f 2 (h []),也就是
h $ (h []) (2:)
如果它是这样工作的。这让我看起来很困惑。要匹配foldr 的类型,h 应该是[a] -> [a] 类型,而h [] 将只是[a] 类型,这不适用于(2:)。
我还以另一种方式考虑过,f x g 返回一个类型为([a] -> [a]) -> [a] 的函数,考虑到之后应用id,这有点道理。但后来我意识到我仍然不知道h 在这里做什么。看起来h 将上次的g (x:) 传送到下一个应用程序。
当我想到将fold 用作累加器时,我是否错过了什么?
如果有人能帮我解决这个问题,我将不胜感激。
【问题讨论】:
-
您不能以这种方式简化为
h [],因为h未定义:此时没有为此传递任何参数。您可以改为缩减为\h -> h [],这表示以后仍必须提供h。继续:f 2 (\h -> h []) = ... -
foldr只将两个参数传递给f。替换后,您将得到\h -> h $ (const []) (1:)
标签: function haskell functional-programming fold accumulate