Cuando es una función parcial Scala no es una función parcial?
Pregunta
Si bien la creación de un mapa de cadena de funciones parciales me encontré con un comportamiento inesperado. Cuando creo una función parcial como un elemento del mapa que trabaja muy bien. Cuando asigno a un val invoca en su lugar. Intentar invocar la comprobación genera un error. Se esperaba esto? ¿Estoy haciendo algo tonto? Comentario la check()
para ver la invocación. Estoy usando Scala 2.7.7
def PartialFunctionProblem() = {
def dream()() = {
println("~Dream~");
new Exception().printStackTrace()
}
val map = scala.collection.mutable.HashMap[String,()=>Unit]()
map("dream") = dream() // partial function
map("dream")() // invokes as expected
val check = dream() // unexpected invocation
check() // error: check of type Unit does not take parameters
}
Solución
Para mayor comodidad, Scala permite omite vaciar parens Al llamar a un método, pero es lo suficientemente inteligente como para ver que el tipo esperado en el primer caso es ()=>Unit
, por lo que no quita todos los parens para usted; en cambio, convierte el método en una función para usted.
En el caso val check
, sin embargo, se ve como resultado consiguiendo llamada a la función asignada a una variable. De hecho, los tres de estos hacen exactamente lo mismo:
val check = dream
val check = dream()
val check = dream()()
Si desea activar el método en una función, se coloca _
después del método en lugar de la lista de argumentos (s) . Por lo tanto,
val check = dream() _
hará lo que usted desea.
Otros consejos
Bueno, el problema es que lo tienes todo mal. : -)
Aquí están algunos errores conceptuales:
def dream()() = {
println("~Dream~");
new Exception().printStackTrace()
}
Esto no es una función parcial. Este es un método curry con dos listas de parámetros vacíos que devuelve Unit
.
val map = scala.collection.mutable.HashMap[String,()=>Unit]()
El tipo de los valores de este mapa no es función parcial, pero la función. Específicamente, Function0[Unit]
. Una función parcial tendría tipo PartialFunction[T, R]
.
map("dream") = dream() // partial function
Lo que sucede aquí es que Scala conversos el método aplicado parcialmente en una función. Esto no es una tarea sencilla. Scala realiza la conversión porque el tipo inferencer puede adivinar el tipo correcto.
val check = dream() // unexpected invocation
Aquí hay ningún tipo es lo esperado para ayudar al tipo inferencer. Sin embargo, las listas de parámetros vacíos pueden ser omitidos, así que esto es sólo una llamada al método.