函数文字拼图上的隐式参数

Implicit parameter on function literal puzzle

我试图弄清楚函数文字是否可以有隐式参数。

我在下面的 post 中发现 Function literal 不能,因为它是没有隐式参数的 FunctionN 对象。

Scala Functional Literals with Implicits

但是答案包含以下技巧

val sum2 = (a: Int) => {implicit b: Int => a + b}

我试着玩弄它,但我不太确定为什么它会编译以及构造 implicit b: Int => a + b 究竟代表什么。

我试试看

val sum2 = (a: Int) => {(implicit b: Int) => a + b}

val sum2 = (a: Int) => {implicit (b: Int) => a + b}

两者都不编译。在这两种情况下,我的假设是我们在 implicit b: Int => a + b 中返回一个函数文字。如果是这样,为什么上面的构造不起作用。以及为什么以下构造有效:

val sum2 = (e:Int) => { (f:Int) => e + f}

有人可以帮助我了解这里发生了什么吗?我觉得很奇怪,很费解。

这并不是真正地创建带有隐式参数的函数。该函数仍然只有一个普通的显式参数,只是在该函数的主体中该参数也是一个隐式值。

这与您这样做完全一样:

{ b: Int => implicit val bImplicit: Int = b; a + b }

所以在你的情况下它是无用的,因为你仍然必须在调用函数时显式地传递 bsum2(1)(2)

If so why the constructs above do not work.

因为SLS 6.23 Anonymous Functions指定语法为

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

请注意 EBNF 表示法 (‘(’ 之间的含义差异。前者表示grouping。如果以下是合法的

(implicit b: Int) => ???

然后 ResultExpr 规则将指定 ‘(’‘)’ 类似于它们在 Bindings 规则中的存在方式。

来自同一个 SLS 部分

A named parameter of an anonymous function may be optionally preceded by an implicit modifier. In that case the parameter is labeled implicit; however the parameter section itself does not count as an implicit parameter section. Hence, arguments to anonymous functions always have to be given explicitly.