高阶和​​curried函数之间的区别

时间:2013-09-10 14:09:19

标签: f# functional-programming functor higher-order-functions currying

我正在阅读一本书Functional Programming Using F#says(第33页),高阶函数声明

部分
  

我们已经看到了高阶内置函数,如(+)和(<<<)

并在本节末尾

  

也可以通过在let-declaration中提供如下参数来定义高阶函数:

let weight ro s = ro * s ** 3.0;;

然而,在question that I asked earlier today(最初标题为“我应该何时将我的函数编写为高阶函数”)的底部有一些有用的注释,似乎对这些示例是否实际上存在疑问高阶函数。

wikipedia definition of higher-order function是:

  

高阶函数(也是函数形式,函数或函子)是至少执行以下操作之一的函数:(i)将一个或多个函数作为输入; (ii)输出一个函数。

一方面,我可以看到像(+)weight这样的函数可能被视为高阶函数,因为给定一个参数它们返回一个函数。另一方面,我可以看到它们被恰当地视为咖喱功能。我正在学习F#作为一个自学项目,并希望明确这些概念,因此本网站的答案和讨论特别有用。

我的问题是,这些功能的正确用语是什么,也许更重要的是,人们通常如何使用“高阶函数”和“咖喱函数”这些术语?

2 个答案:

答案 0 :(得分:12)

我认为您可以说 curried函数是一个高阶函数,它返回一个函数作为结果。

curried函数是一个类似于a -> b -> c的函数 - 如果添加括号(不改变类型)a -> (b -> c),你可以看到这也是高阶函数

但是,您可以编写高阶但不是咖喱的函数。例如,以下简单函数需要一些函数f并调用它两次:

let runTwice f = f(); f();

此函数的类型为(unit -> unit) -> unit,因此它不是curry(它只需要一些输入并返回单位值),但它是高阶的,因为参数是一个函数。

尽管像(+)这样的函数在技术上是高阶的(类型是int -> (int -> int)),但我认为它们不是高阶的好例子,因为你通常不会在更高阶的方式(但它偶尔会有用)。更高阶函数的更典型示例是像List.map这样的函数,它们将函数作为参数。

答案 1 :(得分:5)

粗略地说,curried函数是高阶函数的子集。高阶函数在结果中接受函数作为参数或返回函数。 Curried函数是以curry形式编写的多元函数,作为接受第一个参数的函数,并返回接受第二个参数的函数,等等。

这就是Tomas上面所说的。但是,我认为这里有一个微妙之处。我不认为所有返回函数的函数都是curry,我认为Tomas'声明“如果你添加括号(不改变类型)”在F#中是不准确的。

特别地,考虑一个带参数的函数,有副作用然后返回另一个带另一个参数并返回结果的函数:

let f x =
  printfn "%d" x
  fun y -> x+y

F#推断类型:

val f : int -> (int -> int)

请注意,它在那里放了看似多余的括号,我相信,正是因为这些类型之间存在细微差别。

此外,虽然这个函数返回一个函数作为结果,但我不认为它因为副作用而有资格作为curried函数。这不是以咖喱形式重写的多元函数......