【问题标题】:Difference between higher order and curried functions高阶函数和柯里化函数之间的区别
【发布时间】:2013-09-14 07:08:58
【问题描述】:

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

部分

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

在本节的末尾

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

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

然而,question that I asked earlier today(最初的标题是“我什么时候应该将我的函数编写为高阶函数”)的底部有一些有用的 cmets,这似乎让人怀疑这些示例是否实际上更高-排序函数。

wikipedia definition of higher-order function 是:

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

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

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

【问题讨论】:

  • 那个重量例子当然不是我认为的高阶函数。它需要几个浮点数并返回一个浮点数。这只是一个函数。
  • @Kit 来自 Tomas Petricek 的回答,柯里化函数是高阶函数的特例。在weight 示例中,weight ro 返回一个float -> float 函数,因此技术上 是一个高阶函数。但更常见的是称它为 curried 函数,就像我的宠物 Fido 更常见的称呼是狗而不是哺乳动物一样。
  • 哎呀,我的(基本)错误。 ;-)

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


【解决方案1】:

我想你可以说 curried 函数 是一个 higher-order 函数,它返回一个函数作为结果。

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

但是,您可以编写高阶但不是柯里化的函数。例如,下面这个简单的函数接受一些函数f 并调用它两次:

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

这个函数有一个类型(unit -> unit) -> unit,所以它不是柯里化的(它只是接受一些输入并返回单位值),但它是高阶的,因为参数是一个函数。

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

【讨论】:

  • 从技术上讲,IIRC,如果我们将类型绘制为节点为箭头的有向树,则类型的顺序是路径上左分支的最大数量。在这个定义下,仅仅柯里化函数不是高阶(即>1阶)。
  • 我不确定您的定义 - 我认为普遍接受的定义是 ord(t1 -> t2) = 1 + max(ord(t1), ord(t2))ord(base) = 1
  • 是的。有人教我“我的”定义,我想我记错了它定义的术语。
【解决方案2】:

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

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

具体来说,考虑一个接受参数的函数,具有副作用,然后返回另一个接受另一个参数并返回结果的函数:

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

F# 推断类型:

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

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

此外,虽然这个函数返回一个函数作为其结果,但我认为它不符合柯里化函数的条件,因为它有副作用。这不是以柯里化形式重写的多元函数...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-17
    • 1970-01-01
    • 2012-04-25
    • 1970-01-01
    • 2016-01-01
    • 2021-02-07
    • 2012-10-06
    • 1970-01-01
    相关资源
    最近更新 更多