如何隐藏匿名函数中的多个参数?

时间:2015-04-24 14:09:37

标签: scala

如果我们有一个接受匿名函数A => B作为参数的方法,我们可以在调用中隐含A

def impl(a: Int)(f: Int => Int): Int = f(a)

impl(a) { implicit z =>
    ...
}

但我们可以使用具有多个参数的匿名函数来执行此操作吗?

def impl(a: Int, b: Int)(f: (Int, Int) => Int): Int = f(a, b)

理想情况下,这可能会起到以下作用:

impl(1, 2) { implicit (a, b) => // wrong
    ...
}

impl(1, 2) { (implicit a, implicit b) => // also wrong
    ...
}

我可以使用A => B => C解决此问题,而不是:

def impl(a: Int, b: Int)(f: Int => Int => Int): Int = f(a)(b)

impl(1, 2) { implicit a => implicit b =>
    ...
}

但有没有一种方法可以做到这一点而不需要讨论函数?

显而易见,但Int只是一个虚拟占位符。

1 个答案:

答案 0 :(得分:4)

不,这是不可能的。从规范的6.23 Anonymous Functions部分,匿名函数语法是:

Expr            ::=  (Bindings | ['implicit'] id | '_') '=>' Expr
ResultExpr      ::=  (Bindings | (['implicit'] id | '_') ':' CompoundType) '=>' Block
Bindings        ::=  '(' Binding {',' Binding} ')'
Binding         ::=  (id | '_') [':' Type]

正如您所看到的,implicit案例是特殊的,只有1个标识符,而重复案例Bindings(使用EBNF的重复语法{...} )排除使用implicit

本节中implicit唯一添加的详细信息包括:

  

匿名函数的命名参数可以选择在隐式修饰符之后。在这种情况下,参数标记为隐含;但是参数部分本身并不算作定义为here的意义上的隐式参数部分。因此,必须明确给出匿名函数的参数。

我认为这篇文章还应该澄清这只适用于单个参数(例如“具有1个参数的匿名函数的命名参数......”)

当然,最简单的解决方法是避开语法糖并将匿名函数参数重新绑定到新的隐式变量:

impl(a) { (b, c) =>
    implicit val (impB, imbC) = (b, c)
    ...
}