function - Literales funcionales Scala con implícitos
literals implicit (3)
En este fragmento
scala> val sum2 = (a: Int) => (b: Int) => a + b
sum: (Int) => (Int) => Int = <function1>
Tenga en cuenta que el tipo exacto de sum2
es Function1[Int, Function1[Int, Int]]
. También podría ser escrito como
val sum2 = new Function1[Int, Function1[Int, Int]] {
def apply(a: Int) = new Function1[Int, Int] {
def apply(b: Int) = a + b
}
}
Ahora, si intentas hacer b
implícito, obtienes esto:
scala> val sum2 = new Function1[Int, Function1[Int, Int]] {
| def apply(a: Int) = new Function1[Int, Int] {
| def apply(implicit b: Int) = a + b
| }
| }
<console>:8: error: object creation impossible, since method apply in trait Function1 of type (v1: Int)Int is not defined
def apply(a: Int) = new Function1[Int, Int] {
^
O, en otras palabras, las interfaces de la función no tienen parámetros implícitos, por lo que cualquier cosa con un parámetro implícito no es una Function
.
Perdóname si esto ya se ha pedido en otra parte. Tengo una pregunta de sintaxis de Scala que involucra valores de función y parámetros implícitos.
Me siento cómodo usando implícitos con la función de curry de Scala. Por ejemplo, si tuviera una función de suma y quisiera que el segundo argumento fuera implícito:
scala> def sum(a: Int)(implicit b: Int) = a + b
sum: (a: Int)(implicit b: Int)Int
¿Hay alguna manera de hacer esto usando la sintaxis de la función-valor? Ignorando lo implícito por un momento, normalmente escribo valores de función al curry como este:
scala> val sum2 = (a: Int) => (b: Int) => a + b
sum: (Int) => (Int) => Int = <function1>
Sin embargo, la firma de función en el segundo enfoque es muy diferente (el curry se expresa explícitamente). El simple hecho de agregar la palabra clave implícita a b no tiene mucho sentido y el compilador también se queja:
scala> val sum2 = (a: Int) => (implicit b: Int) => a + b
<console>:1: error: ''=>'' expected but '')'' found.
val sum2 = (a: Int) => (implicit b: Int) => a + b
^
Además, la suma de aplicación parcial desde el primer enfoque para obtener una función-valor también causa problemas:
scala> val sumFunction = sum _
<console>:14: error: could not find implicit value for parameter b: Int
val sumFunction = sum _
^
Esto me lleva a creer que las funciones que tienen parámetros implícitos deben tener dichos parámetros determinados cuando se crea el valor de la función, no cuando el valor de la función se aplica más adelante. ¿Es este realmente el caso? ¿Puedes usar un parámetro implícito con un valor de función?
¡Gracias por la ayuda!
Intenta sobrecargar el método de aplicación.
scala> val sum = new Function1[Int, Function1[Int, Int]] {
| def apply(a: Int) = (b: Int) => a + b
| def apply(a: Int)(implicit b: Int) = a + b
|}
sum: java.lang.Object with (Int) => (Int) => Int{def apply(a:Int)(implicit b: Int): Int} = <function1>
scala> sum(2)(3)
res0: Int = 5
scala> implicit val b = 10
b: Int = 10
scala> sum(2)
res1: Int = 12
scala> val sum2 = (a: Int) => {implicit b: Int => a + b}
sum2: (Int) => (Int) => Int = <function1>
Esto solo hará de b un valor implícito para el alcance del cuerpo de la función, por lo que puede llamar a métodos que esperan un Int implícito.
No creo que puedas tener argumentos implícitos para las funciones, ya que no está claro cuál es la función. ¿Es Int => Int
o () => Int
?
Lo más cercano que encontré es:
scala> case class Foo(implicit b: Int) extends (Int => Int) {def apply(a: Int) = a + b}
defined class Foo
scala> implicit val b = 3
b: Int = 3
scala> Foo()
res22: Foo = <function1>
scala> res22(2)
res23: Int = 5