scala - Scala 中的 curry 和闭包

标签 scala closures currying

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

我使用了之前在演示过程中介绍的函数:

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

我创建了一个柯里化(Currying)版本(如果我错了,请纠正我!):

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

所以我不确定的第一部分是“curried_safe_division 叫做 curry 吗?”

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

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.

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

最佳答案

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

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

函数divideSix不是一个闭包。这是一个简单的函数,它接受一个整数并返回一个整数。然而,什么是闭包,是 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。它“在 x 上关闭”。当您说 val divideSix = curried_safe_division(6) 时,您将采用该闭包,为其提供 6 作为参数 x 的值,并将其分配给 divideSix。但 divideSix 本身并不是一个闭包。它不会关闭任何东西。它只需要一个整数参数并将其除以六。

我发现有些人倾向于将结果函数值(在我们的示例中为 divideSix)称为“闭包”,因为它是部分应用某些函数(在我们的示例中 curried_safe_division )并产生一个函数(在我们的示例中在注释之间标记),它是一个实际的闭包。我对此很满意。只要您了解其机制,就可以轻松找到术语。

关于scala - Scala 中的 curry 和闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43188547/

相关文章:

json - 具有 json 解析器的单元测试 Play Controller 操作

java - 如何从 Akka Streams Sink 中抛出的异常中恢复?

swift - 闭包和静态函数

Node.js:循环中的闭包

javascript - 直接调用匿名函数与通过变量调用之间的区别?

scala - Akka context.actorOf 不工作

scala - Scala 中的儒略日期到公历日期转换

c++ - 将闭包作为“类方法指针”?

Haskell: `Map (a,b) c` 与 `Map a (Map b c)` 对比?

scala - 如何在 Scala 中对函数进行柯里化(Currying)