currying和高阶函数之间的区别

igx*_*igx 9 scala

看看Scala中的编程(控件抽象)我看到这两个具有相同效果的例子:

1.高阶函数

def withPrintWriter(file: File, op: PrintWriter => Unit) {
  val writer = new PrintWriter(file)
  try {
    op(writer)
  } finally {
    writer.close()
  }
}
Run Code Online (Sandbox Code Playgroud)

2.卷曲功能

def withPrintWriter(file: File)(op: PrintWriter => Unit) {
  val writer = new PrintWriter(file)
  try {
    op(writer)
  } finally {
    writer.close()
  }
}
Run Code Online (Sandbox Code Playgroud)

他们之间有什么区别?我们能否始终以两种方式获得相同的结果?

Aar*_*rup 16

高阶函数curried函数的概念通常以正交方式使用.甲高阶函数是一个简单的函数,它需要一个函数作为参数或返回的函数,结果,并且其可以或可以不被咖喱.在一般用法中,引用高阶函数的人通常在谈论将另一个函数作为参数的函数.

咖喱功能,在另一方面,是一个返回的功能作为其结果.完全curried函数是单参数函数,它返回普通结果或返回完全curried函数.注意,curried函数必然是高阶函数,因为它返回一个函数作为其结果.

因此,您的第二个示例是返回高阶函数的curried函数的示例.这是curried函数的另一个例子,它没有将函数作为参数,以各种(几乎相当的)方式表示:

def plus(a: Int)(b:Int) = a + b
def plus(a: Int) = (b: Int) => a + b
val plus = (a: Int) => (b: Int) => a + b
Run Code Online (Sandbox Code Playgroud)


dre*_*xin 6

高阶函数是将函数作为参数或返回函数或两者兼有的函数.

def f(g: Int => Int) = g(_: Int) + 23

scala> f(_ + 45)
res1: Int => Int = <function1>

scala> res1(4)
res2: Int = 72
Run Code Online (Sandbox Code Playgroud)

这是一个更高阶的函数,它将函数作为参数并返回另一个函数.如您所见,高阶函数是curry的先决条件.咖喱功能看起来像这样:

def curry[A,B,C](f: (A,B) => C) = (a: A) => (b: B) => f(a,b)

scala> curry((a: Int, b: Int) => a+b)
res3: Int => (Int => Int) = <function1>

scala> res3(3)
res4: Int => Int = <function1>

scala> res4(3)
res5: Int = 6
Run Code Online (Sandbox Code Playgroud)

所以回答你的问题:它们是两个不同的概念,其中一个(高阶函数)是另一个(currying)的预先获取.