2017-04-03 114 views
3

我正在准备一个关于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 
} 

所以第一部分,我我不确定是“curried_safe_division叫咖喱?”

然后我介绍了一些代码来说明如何讨好功能允许程序员高效地重用功能:

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 可以存储为变量(称为“第一级功能”),其具有访问本地其它变量的范围进行特殊能力的函数它是在创建

我看了多个资源联机,维基百科网页和这个计算器的问题:What is a 'Closure'?但它仍然是不超级明确

+0

“curried_safe_division叫咖喱?” “咖喱”是什么意思? – pedrofurla

+0

现在关闭,我读了所有的https://en.wikipedia.org/wiki/Closure_(computer_programming)。 – pedrofurla

+0

@pedrofurla我不知道“咖喱”应该是什么意思,但我的理解是,它应该是从你产生其他部分定义的功能的“基本功能” – Daniel

回答

4

curried_safe_division是一个函数。这与safe_division不同,这是一种方法。

此外,curried_safe_division咖喱功能。当你把safe_division变成一个函数时,你通常会得到的是(Int, Int) => Option[Double]。通过将其更改为Int => Int => Option[Double],您的咖喱的功能。

函数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)部分地应用一些功能的功能,并产生了函数(在我们的例子中的注释之间标记),这是一个实际的结束。我很好。只要你了解机制,就很容易找到围绕术语的方法。

+0

我希望我可以upvote你两次,“关闭x”很容易记住 – Daniel

+0

很高兴我可以帮助。如果你还没有,请检查[this](http://www.artima.com/pins1ed/functions-and-closures.html#8.7)。 – slouc

+0

从你给我的链接:“结果函数值,它将包含对捕获的更多变量的引用,因此称为闭包,因为函数值是关闭开放项的行为的最终产物,( x:Int)=> x + more。“ @slouc我是不是通过做curried_safe_division(6)来“关闭开放期限”,因此curried_safe_division(6)会是关闭吗? – Daniel

1

柯里里其实比你的例子简单得多。您不需要同时引入方法/功能区分。

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

从那里,你可以介绍eta expansionsafe_division(2)_,创造Int => Option[Double]类型的函数。

+0

非常感谢您的支持,我认为这个语法可能会更清晰。功能/方法的区别并不是我在这个演示中要解决的问题,老实说,我必须先学习自己 – Daniel