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

Too*_*one 5 f# functional-programming currying functor higher-order-functions

我正在阅读一本书,使用F#进行功能编程,其中说明(第33页),在高阶函数声明部分

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

在本节结尾处

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

let weight ro s = ro * s ** 3.0;;
Run Code Online (Sandbox Code Playgroud)

然而,我在今天早些时候提出的一个问题的底部有一些有用的评论(最初的标题是"我什么时候应该把我的函数写成更高阶函数"),似乎对这些例子是否实际上更高有疑问 -订单功能.

高阶函数的维基百科的定义是:

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

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

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

Tom*_*cek 12

我想你可以说curried函数是一个高阶函数,它返回一个函数作为结果.

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

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

let runTwice f = f(); f();
Run Code Online (Sandbox Code Playgroud)

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

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


Jon*_*rop 5

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

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

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

let f x =
  printfn "%d" x
  fun y -> x+y
Run Code Online (Sandbox Code Playgroud)

F#推断类型:

val f : int -> (int -> int)
Run Code Online (Sandbox Code Playgroud)

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

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