我不明白这里发生了什么?任何人都可以解释这段代码吗? 这个函数如何计算长度?Haskell高阶函数来计算长度
callength = foldr (\_ n -> 1 + n) 0
为什么它使用lambda,下划线,下划线和n之间的空格和右边的零?
我不明白这里发生了什么?任何人都可以解释这段代码吗? 这个函数如何计算长度?Haskell高阶函数来计算长度
callength = foldr (\_ n -> 1 + n) 0
为什么它使用lambda,下划线,下划线和n之间的空格和右边的零?
(\_ n -> 1 + n)
只是表示一个函数,它接受两个参数,并返回比第二个参数多一个的参数。下划线仅表示参数被忽略。为了比较,因为没有使用通配符模式(下划线)的顶级声明,这个功能看起来像:
foo x n = 1 + n
现在,这里是一个例子列表:
[1, 2, 3, 4]
这其实恰恰是语法糖:
1 : 2 : 3 : 4 : []
什么foldr
确实是递归与它给出的函数替换每个(:)
和[]
用函数后面的参数(零)。所以,foldr f z [1, 2, 3, 4]
任何f
和z
看起来是这样的:
f 1 (f 2 (f 3 (f 4 z)))
(这就是为什么foldr (:) []
刚刚返回相同的列表,你给它 - 它结束了重构原始列表结构。)
在这情况下,使用功能foo
和零0,它看起来像:
foo 1 (foo 2 (foo 3 (foo 4 0)))
我们知道,foo
忽略它的第一个参数,并返回一个铁道部而不是第二个论点。因此,这是相同的:
1 + (1 + (1 + (1 + 0)))
其为4,则列表的长度。基本上,折叠会忽略列表中的每个元素,并为每个元素添加一个累加器,给出长度。 0用于结束的全过程,并且由于空列表的长度是0
要查看此更详细地,我们可以展开每个呼叫一步步骤:
foldr foo 0 (1 : 2 : 3 : 4 : [])
foo 1 (foldr foo 0 (2 : 3 : 4 : []))
1 + foldr foo 0 (2 : 3 : 4 : [])
1 + foo 2 (foldr foo 0 (3 : 4 : []))
1 + 1 + foldr foo 0 (3 : 4 : [])
1 + 1 + foo 3 (foldr foo 0 (4 : []))
1 + 1 + 1 + foldr foo 0 (4 : [])
1 + 1 + 1 + foo 4 (foldr foo 0 [])
1 + 1 + 1 + 1 + foldr foo 0 []
1 + 1 + 1 + 1 + 0
1 + 1 + 1 + 1
1 + 1 + 2
1 + 3
4
哇。这是Haskell关键基础的一个非常耐心的解释。 +1。 – 2012-02-15 20:23:55
我认为你会像任何关于Haskell的书的第三章那样找到这个问题的答案。这是一个非常基本的东西。 – 2012-02-15 17:23:36
如果你不喜欢lambda,你可以使用'foldr(((+1)。)。(flip const))0'而不是... – Landei 2012-02-15 18:45:01
你知道'foldr'是什么,它是如何工作的?那么,ehird无论如何都给了它一个相当彻底的解释。 [学习你一个Haskell](http://learnyouahaskell.com/)强烈推荐作为“Haskell入门”书,解释lambda表达式,下划线,折叠,函数等。 – 2012-02-15 21:37:00