Scala:将curried函数作为参数传递

时间:2013-10-26 17:07:14

标签: scala functional-programming

是否可以执行以下操作?

def takeCurriedFnAsArg(f: (Int)(implicit MyClass) => Result)

1 个答案:

答案 0 :(得分:10)

是的,这是可能的。

当您将第二个curried参数标记为implicit时,该函数似乎 类型为

Int => (MyClass => Result) => ResultOfFunction 
如果curried高阶函数参数是常规参数,那将是

;相反,它看起来像这样:

Int => ResultOfFunction

这是一个简单的例子:

scala> def curriedFn(i : Int)(implicit func : String => Int) : Boolean = (i + func("test!")) % 2 == 0
curriedFn: (i: Int)(implicit func: String => Int)Boolean

scala> implicit val fn : String => Int = s => s.length
fn: String => Int = <function1>

scala> curriedFn _
res4: Int => Boolean = <function1>

如您所见,implicit参数已被“删除”。为什么以及如何?对于比我更有知识的人来说,这是一个问题。如果我不得不猜测,我会说编译器直接用隐含值替换参数,但这很可能是假的。

无论如何,除了离题之外,这里有一个与你的情况非常相关的例子:

scala> def foo(func : Int => Boolean) = if(func(3)) "True!" else "False!"
foo: (func: Int => Boolean)String

scala> foo(curriedFn)
res2: String = True!

现在,如果第二个函数参数不是隐式的:

scala> def curriedNonImplicit(i : Int)(fn : String => Int) : Boolean = (i + fn("test!")) % 2 == 0
curriedNonImplicit: (i: Int)(fn: String => Int)Boolean

scala> curriedNonImplicit _
res5: Int => ((String => Int) => Boolean) = <function1>

如您所见,函数的类型有点不同。这意味着解决方案也会有所不同:

scala> def baz(func : Int => (String => Int) => Boolean) = if(func(3)(s => s.length)) "True!" else "False!"
baz: (func: Int => ((String => Int) => Boolean))String

scala> baz(curriedNonImplicit)
res6: String = True!

您必须直接在方法内指定函数,因为它之前没有隐式提供。