Scala 中的 Curry 和闭包

Curry and closures in Scala

我正在准备有关 Scala 和函数式编程的演示文稿,但我不确定两个概念。

我使用了之前在演示中介绍的功能:

def safe_division(x: Int, y: Int) : Option[Double] = {
  if(y != 0)
    Some(x / y.toDouble)
  else
    None
}

我创建了一个柯里化版本(如有错误请指正!):

val curried_safe_division: (Int) => (Int) => Option[Double] = {
  (x) => 
    (y) =>     
      if(y != 0)
        Some(x / y.toDouble)
      else
        None
}

所以我不确定的第一部分是 "is curried_safe_division called the curry?"

然后我介绍一些代码来展示柯里化函数如何让程序员有效地重用功能:

val divideSix = curried_safe_division(6)
divideSix(3)
// prints: Some(2.0)
divideSix(6)
// prints: Some(1.0)

我在这里说 divideSix 是闭包是对的吗? curried_safe_division 也不是闭包吗? 我正在使用这个定义:

https://softwareengineering.stackexchange.com/a/40708 a function that can be stored as a variable (referred to as a "first-class function"), that has a special ability to access other variables local to the scope it was created in.

我在网上阅读了多种资源、维基百科页面和这个 Whosebug 问题:What is a 'Closure'? 但它仍然不是 super清除

curried_safe_division是一个函数。这不同于safe_division,后者是一种方法。

此外,curried_safe_division 是一个 柯里化函数。当您将 safe_division 转换为函数时,您通常会得到 (Int, Int) => Option[Double]。通过将其更改为 Int => Int => Option[Double],您 curried 函数。

函数divideSix不是闭包。这是一个简单的函数,接受一个整数和 returns 一个整数。然而什么是闭包是 curried_safe_division:

中的内部函数
val curried_safe_division: (Int) => (Int) => Option[Double] =
    (x) => 
    // function below is a closure   
      (y) =>     
        if(y != 0)
          Some(x / y.toDouble)
        else
          None
    // end of closure
  }

你可以清楚地看到它依赖于x但不将其作为自己的参数;相反,它使用了外部作用域中的 x。它"closes over x"。当你说 val divideSix = curried_safe_division(6) 时,你正在使用那个闭包,为它提供 6 作为参数 x 的值,并将其分配给 divideSix。但是 divideSix 本身并不是闭包。它不会关闭任何东西。它只需要一个整数参数并将其除以六。

我看到有些人倾向于将结果函数值(在我们的示例中为 divideSix)称为 "closure",因为它是部分应用某些函数(curried_safe_division 在我们的例子中)并产生一个函数(在我们的例子中标记在注释之间)这是一个实际的闭包。我没意见。只要您了解机制,就很容易找到术语。

柯里化实际上比您的示例简单得多。不需要同时引入method/function区分

// a curried safe_division method
def safe_division(x: Int)(y: Int) : Option[Double] =
  if (y != 0) Some(x / y.toDouble)
  else        None

从那里你可以引入 safe_division(2)_,它创建了一个 Int => Option[Double].

类型的函数