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.
An anonymous function is a function with no name which can be used once they're created. The anonymous function can be used in passing as a parameter to another function or in the immediate execution of a function.
An anonymous function in javascript is not accessible after its initial creation. Therefore, we need to assign it to a variable, so that we can use its value later. They are always invoked (called) using the variable name. Also, we create anonymous functions in JavaScript, where we want to use functions as values.
They're called anonymous functions because they aren't given a name in the same way as normal functions. Because functions are first-class objects, we can pass a function as an argument in another function and later execute that passed-in function or even return it to be executed later.
The () makes the anonymous function an expression that returns a function object. An anonymous function is not accessible after its initial creation. Therefore, you often need to assign it to a variable. In this example, the anonymous function has no name between the function keyword and parentheses () .
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 (e.g. "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)
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With