2016-08-14 54 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

相关问题