Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declare a Function `type` with `implicit` parameters

Tags:

scala

implicit

Is it somehow possible to declare something like

type F = (Int, Boolean)(implicit String) => Unit

in Scala?

like image 555
scravy Avatar asked Feb 19 '16 10:02

scravy


People also ask

How do you pass an implicit parameter?

The implicit parameter in Java is the object that the method belongs to. It's passed by specifying the reference or variable of the object before the name of the method. An implicit parameter is opposite to an explicit parameter, which is passed when specifying the parameter in the parenthesis of a method call.

What is an implicit parameter?

Implicit parameters are the parameters that are passed to a function with implicit keyword in Scala, which means the values will be taken from the context in which they are called.

What is implicit parameter in C++?

Implicit and dynamic parameters are proposed as a general means to reduce the length of argument lists of function calls without resorting to dangerous global variables. In C++, these new kinds of parameters constitute a generalization of parameters with default arguments, whose values can be omitted in function calls.

What is an example of implicit argument?

Implicit arguments are arguments that occur in Logical Form, but are omitted in the syntax. Consider the following sentences: (1) Mary was run over by a car. (2) Mary was run over with a car.


1 Answers

There is a very important distinction in Scala between "function" and "method":

Functions are values, and can't take arguments by-name, can't be polymorphic, can't be variadic, can't be overloaded, and can't have implicit parameters. While methods can have these, they cannot be passed around as values.

Function types are just traits in the standard library, of the following form:

trait FunctionN[T1, ..., TN, R] {
  def apply(x1: T1, ..., xN: TN): R
}

Note how the apply method in these types does not have an implicit parameter list. Therefore, functions won't ever have implicit parameters.

So if you want to pass "functions" that take implicit parameters, you must create your own trait:

trait Function2I1[T1, T2, I1, R] {
  def apply(a1: T1, a2: T2)(implicit i1: I1): R
}

type F = Function2I1[Int, Boolean, String, Unit]

Now you can create instances of type F (albeit not with shiny lambda syntax):

val f = new F {
  override def apply(x: Int, y: Boolean)(implicit z: String): Unit = ???
}
implicit val x = "hi"
f(1, true) // implicitly passes x

If you want curried functions without implicit parameters, just write (Int, Boolean) => String => Unit.

If you want to convert a method to a function, use a lambda:

class A {
  def f(a: String)(implicit b: String): String = a + b
}
val a = new A
val m = a.f(_) // takes the implicit in this scope
like image 187
Ven Avatar answered Oct 22 '22 18:10

Ven