【问题标题】:Haskell higher order function to calculate lengthHaskell高阶函数计算长度
【发布时间】:2012-02-15 16:36:31
【问题描述】:

我不明白这里发生了什么?有人可以解释一下这段代码吗? 这个函数是怎么计算长度的?

callength = foldr (\_ n -> 1 + n) 0

为什么它使用 lambda、下划线、下划线和 n 之间的空格以及右侧的零?

【问题讨论】:

  • 我想你会在任何一本关于 Haskell 的书的第三章中找到这个问题的答案。这是一个非常基本的东西。
  • 如果你不喜欢 lambda,你可以改用foldr (((+1).).(flip const)) 0...
  • 您知道foldr 是什么以及它是如何工作的吗?好吧,无论如何,ehird 已经给出了相当详尽的解释。 Learn You a Haskell 强烈推荐作为一本“Haskell 入门”一书,解释 lambda、下划线、折叠、函数等。

标签: haskell higher-order-functions


【解决方案1】:

(\_ n -> 1 + n) 仅表示一个接受两个参数的函数,并且返回的参数比第二个参数多一个。下划线仅表示忽略参数。作为比较,作为不使用通配符模式(下划线)的顶级声明,此函数如下所示:

foo x n = 1 + n

现在,这是一个示例列表:

[1, 2, 3, 4]

这实际上只是语法糖:

1 : 2 : 3 : 4 : []

foldr 所做的是将每个(:) 递归地替换为给定的函数,并将[] 替换为函数后面的参数()。所以,foldr f z [1, 2, 3, 4] 对于任何 fz 看起来像这样:

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。
猜你喜欢
  • 1970-01-01
  • 2017-04-21
  • 1970-01-01
  • 2011-12-13
  • 1970-01-01
  • 2012-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多