【发布时间】:2015-12-21 21:10:12
【问题描述】:
在短暂的中断之后,我再次开始学习 Haskell,目前我正在尝试更好地了解递归和 lambda 表达式在 Haskell 中的工作原理。
在这个:YouTube video 中,有一个函数示例让我非常困惑,就其实际工作方式而言:
firstThat :: (a -> Bool) -> a -> [a] -> a
firstThat f = foldr (\x acc -> if f x then x else acc)
为了清楚起见,因为它对我来说不是很明显,所以我将举一个将这个函数应用于一些参数的例子:
firstThat (>10) 2000 [10,20,30,40] --returns 20, but would return 2000, if none of the values in the list were greater than 10
如果我的假设是错误的,请纠正我。
看来firstThat 需要三个参数:
- 一个接受一个参数并返回一个布尔值的函数。由于
>运算符实际上是一个中缀函数,所以上例中的第一个参数似乎是对>函数的部分应用的结果——这是正确的吗? - 一个与作为第一个参数提供的函数的缺失参数相同类型的未指定值
- 上述类型的值列表
但实际函数firstThat 的定义似乎与其类型声明不同,只有一个参数。由于foldr 通常需要我收集的三个参数,因此会发生某种部分应用。作为 foldr 的参数提供的 lambda 表达式似乎也缺少其参数。
那么,这个功能究竟是如何工作的呢?如果我太密集或只见树木不见森林,我深表歉意,但我就是无法绕开它,这令人沮丧。
任何有用的解释或示例将不胜感激。
谢谢!
【问题讨论】:
-
抱歉错别字,感谢编辑,duplode!
-
顺便说一句,你的
firstThat没有任何递归——仅仅因为foldr帮助你非递归地重写一个递归函数,并不意味着你应该引用任何使用的函数foldr作为递归的。 -
谢谢,我明白你的意思了,当然这是有道理的。我要学习的东西比我想象的要多。
-
也许看到写成
firstThat :: (a -> Bool) -> a -> ([a] -> a)的函数会有所帮助?它接受两个参数并返回一个[a] -> a。
标签: haskell recursion lambda fold partial-application