F# 高阶函数与常用函数的区别

F# 高阶函数与常用函数的区别,f#,functional-programming,functor,higher-order-functions,currying,F#,Functional Programming,Functor,Higher Order Functions,Currying,我正在读一本书(第33页),在高阶函数的声明部分 我们已经看到了高阶内置函数,比如(+)和(我想你可以说curried函数是一个高阶函数,它返回一个函数作为结果 curried函数的类型类似于A->b->c,如果添加括号(不改变类型)A->(b->c),则可以看到这也是更高的顺序 但是,您可以编写高阶但不是curry的函数。例如,以下简单函数接受某个函数f,并调用它两次: let runTwice f = f(); f(); 这个函数有一个类型(unit->unit)->unit,因此它不是c

我正在读一本书(第33页),在高阶函数的声明部分


我们已经看到了高阶内置函数,比如(+)和(我想你可以说curried函数是一个高阶函数,它返回一个函数作为结果

curried函数的类型类似于
A->b->c
,如果添加括号(不改变类型)
A->(b->c)
,则可以看到这也是更高的顺序

但是,您可以编写高阶但不是curry的函数。例如,以下简单函数接受某个函数
f
,并调用它两次:

let runTwice f = f(); f();
这个函数有一个类型
(unit->unit)->unit
,因此它不是curry(它只接受一些输入并返回单位值),但它是高阶的,因为参数是一个函数


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

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

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

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

let f x =
  printfn "%d" x
  fun y -> x+y
F#推断类型:

val f : int -> (int -> int)
请注意,我认为,它在其中添加了看似多余的括号,正是因为这些类型之间存在细微的差异


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

这个权重示例肯定不是我认为的高阶函数。它需要两个浮点,然后返回一个浮点。它只是一个函数。@Kit根据Tomas Petricek的回答,curried函数是高阶函数的特例。在
weight
示例中,
weight ro
返回一个
float->float
函数,因此从技术上讲它是一个高阶函数。但更常见的做法是将其称为curried函数,就像它更常见一样把我的宠物Fido称为狗而不是哺乳动物。哎呀,我的(基本)错误;-)从技术上讲,IIRC,类型的顺序是路径上左分支的最大数量,如果我们将类型绘制为节点为箭头的有向树。在这个定义下,仅仅是curry函数不是更高阶的(即>1阶)。我不确定你的定义-我认为普遍接受的定义是
ord(t1->t2)=1+max(ord(t1),ord(t2))
ord(base)=1
。是的。有人教我“我的”定义,我想我忘了它定义的术语。
val f : int -> (int -> int)