2017-04-03 112 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