2016-08-14 169 views
3

我正在瀏覽spark的測試代碼。雖然我理解下面給出的函數背後的邏輯雙參數化函數在scala中意味着什麼?

這是什麼意思?在下面的語法中定義的好處是什麼?


測試代碼

def withStreamingContext[R](ssc: StreamingContext)(block: StreamingContext => R): R = { 
try { 
    block(ssc) 
} finally { 
    try { 
    ssc.stop(stopSparkContext = true) 
    } catch { 
    case e: Exception => 
     logError("Error stopping StreamingContext", e) 
    } 
    } 
} 

爲什麼它必須這樣定義?爲什麼不能像

def withStreamingContext[R](ssc: StreamingContext,block: StreamingContext => R): R = 

回答

2

好,就可以了。將參數分成兩個或多個參數列表稱爲currying。這樣一個雙參數函數可以變成一個函數,它接受一個參數並返回一個函數,該函數接受一個參數並返回結果。這就是您發佈的代碼中發生的事情。每個n -parameter函數可以看作爲n單參數函數(實際上,在Haskell中所有的函數都是這樣對待的)。

請注意,斯卡拉也有一個部分應用功能的概念,歸結爲同樣的事情。 PAF和currying都只允許你傳遞參數的一個子集,從而接收一個剩下的功能。

例如,

def sum(x: Int, y: Int) = x + y 

可以令行禁止,然後你可以說,例如:

def sum(x: Int)(y: Int) = x + y 
def addTwo = sum(2) _ // type of addTwo is Int => Int 

它給你同樣的功能,但它的第一個參數應用。使用PAF,這將是

def sum(x: Int, y: Int) = x + y 
def addTwo = sum(2, _: Int) 
+0

我試過了在sbt控制檯中的addTwo。但是我收到錯誤缺少方法總和的參數; 如果你想把它作爲一個部分應用的函數,用'_' 按照這個方法 def addTwo = sum(2) 你錯過了_最後。 def addTwo = sum(2) – Knight71

+0

啊是的。但是,如果它在Int => Int的環境中使用,那麼將推斷它並且不需要下劃線,例如, 'List(1,2,3).map(sum(3))'。 – slouc

1

它使用起來更方便:

withStreamingContext(ssc) { 
    doSomething() 
    doSomethingElse() 
} 

VS

withStreamingContext(ssc, { doSomething(); doSomethingElse() }) 
1

的所有

def a(x: Int)(y: Int) = x * y 

首先是

def a(x: Int) = (y: Int) => x * y 

一個語法糖這意味着,你定義返回的功能的方法(關閉了x ) 您可以在不使用所有參數列表的情況下調用此方法並傳遞返回的函數。你也可以部分應用任何其他方法,但我認爲這個語法更清晰。

此外,帶有一元參數列表的函數/方法可以用表達式語法來調用。

withStreamingContext(ssc) { 
    // your code block passed to function 
} 
1

的聲明函數這種風格被稱爲鑽營。它由MosesSchönfinkel獨立推出,後來由Haskell Curry獨立推出,名稱來自它的名字。這個概念實際上源於數學,然後引入計算機科學。

它經常與部分功能應用混淆;主要區別在於對部分應用函數的調用立即返回結果,而不是「currying」鏈中的另一個函數。

scala> def foo (x:Int, y:Int, z:Int) : Int = x + y + z 
foo: (x: Int, y: Int, z: Int)Int 

scala> val pa = foo(1, _:Int, _:Int) 
pa: (Int, Int) => Int = <function2> 

scala> pa(2,3) 
res0: Int = 6 

相反,給定f:(x,y,z) -> n,鑽營產生f':x -> (y -> (z -> n))。換句話說,將每個參數依次應用於先前調用返回的單個參數函數。 在調用f'(1)之後,將返回一個接受單個參數並返回另一個函數的函數,而不是一個接受兩個參數的函數。相反,部分功能應用是指將一些參數固定到一個功能的過程,產生另一個較小功能的功能。這兩個經常混淆。

柯里裏的好處/優點已經被提及elsewhere。你所遇到的主要問題是理解語法,並解釋了它的起源。

+0

感謝您的其他鏈接。 – Knight71

相關問題