简体   繁体   中英

How can I make multiple parameters in an anonymous function implicit?

If we have a method that accepts an anonymous function A => B as a parameter, we can make A implicit in our invocation.

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

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

But can we do this with anonymous functions that have multiple parameters?

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

Ideally, this would work something like:

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

Or

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

I can work around this using A => B => C , instead:

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

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

But is there a way to do this without currying the functions?

It should be obvious, but Int is just a dummy placeholder here.

No, it's not possible. From section 6.23 Anonymous Functions of the spec, the anonymous function syntax is:

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

As you can see, the implicit case is special cased to only have 1 identifier, while the repetitive case Bindings (which uses the repetition syntax {...} of EBNF ) precludes use of implicit .

The only added details for implicit in this section are:

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 in the sense defined here . Hence, arguments to anonymous functions always have to be given explicitly.

I think that this text should also clarify that this only works for a single parameter (eg "A named parameter of an anonymous function that has exactly 1 parameter...")

Of course, the simplest workaround is to eschew the syntactic sugar and rebind the anonymous function parameters to new implicit variables:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM