Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

scala

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.

like image 231
Michael Zajac Avatar asked Apr 24 '15 14:04

Michael Zajac


People also ask

Does anonymous function accept parameters?

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.

Can you assign a anonymous function to a variable?

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.

Can you assign an anonymous function to a variable and pass it as an argument to another function in JavaScript?

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.

How do you make an anonymous function?

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 () .


1 Answers

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)
    ...
}
like image 68
Ben Reich Avatar answered Sep 30 '22 10:09

Ben Reich