Scala 如何使匿名函数中的多个参数隐式?

Scala 如何使匿名函数中的多个参数隐式?,scala,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) { implic

如果我们有一个接受匿名函数
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
    ...
}

我可以使用
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
在这里只是一个虚拟占位符。

不,这是不可能的。根据规范第节,匿名函数语法为:

Expr            ::=  (Bindings | ['implicit'] id | '_') '=>' Expr
ResultExpr      ::=  (Bindings | (['implicit'] id | '_') ':' CompoundType) '=>' Block
Bindings        ::=  '(' Binding {',' Binding} ')'
Binding         ::=  (id | '_') [':' Type]
如您所见,
隐式
大小写是一种特殊的大小写,只有一个标识符,而重复大小写
绑定
(它使用的是重复语法
{…}
)排除了
隐式
的使用

本节中为
implicit
添加的唯一详细信息是:

匿名函数的命名参数前面可以选择隐式修饰符。在这种情况下,参数被标记为隐式;但是,参数部分本身不算作定义意义上的隐式参数部分。因此,匿名函数的参数总是必须显式给出

我认为本文还应该澄清,这只适用于单个参数(例如,“一个匿名函数的命名参数正好有一个参数…”)

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

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

从我在这里看到的情况来看,这仅针对具有单个参数的匿名函数进行讨论。不确定这是否是一个限制。另一方面,Intellij说:
不允许引入隐式参数,因为参数的使用计数不正确
是的,基于这个问题,这似乎是不可能的,而且它只是说,
匿名函数的命名参数前面可能有隐式修饰符。在这种情况下,参数被标记为implicit
,但它没有说明任何限制。这是一个谜。我想如果参数类型相同(如我的示例中所示),可能会导致含蓄性不明确。
impl(a) { (b, c) =>
    implicit val (impB, imbC) = (b, c)
    ...
}