2011-06-23 19 views
7

Estoy teniendo un problema en mi DSL con métodos genéricos sobrecargados resultantes en el compilador me quieren añadir tipos de parámetros explícitos:"Missing tipo de parámetro" en el método genérico sobrecargado teniendo un argumento de función

def alpha[T](fun: Int => T): String = fun(33).toString 

def beta [T](fun: Int => T): String = fun(66).toString 
def beta [T](thunk: => T): String = thunk.toString 

alpha { _ + 11 }   // ok 
beta { _ + 22 }   // "error: missing parameter type for expanded function" 
beta { _: Int => _ + 22 } // ok... ouch. 

Alguna posibilidad puede deshacerse del desorden en la última línea?

EDIT:

Para demostrar que la sobrecarga no es un problema de ambigüedad a scalac per se, aquí es una versión sin parámetro de tipo que funciona perfectamente bien:

def beta(fun: Int => String): String = fun(66).reverse 
def beta(thunk: => String): String = thunk.reverse 

beta(_.toString) // ok 
beta("gaga")  // ok 

Respuesta

4

El problema es que Int => T es también un tipo. Por ejemplo, supongamos que ha definido en apenas el segundo beta:

def beta[ T ](thunk: => T) : String = thunk.toString 

Y ahora se pasa una función Int => Int a ella:

scala> beta((_: Int) + 1) 
res0: String = <function1> 

Por lo tanto, dado que una función se ajusta => T, y que también tiene un Int => T, ¿cómo se supone que Scala sabe cuál quiere? Podría ser un String, por ejemplo:

scala> beta((_: String) + 11) 
res1: String = <function1> 

¿Cómo podría Scala suponer que era una Int? Los ejemplos que ha demostrado que demuestran sobrecarga no tienen la culpa, no demuestran tal cosa, porque se deshizo de los parámetros de tipo en ellos.

1

Como es posible que tenga se dio cuenta, el problema ocurre porque tienes la función beta está sobrecargada. Al definir:

beta { _ + 22 } 

cuales beta qué se puede esperar que llames? Scala no puede saber que _ es Int simplemente porque lo está sumando con 22. Entonces, para este ejemplo en particular, debe definir qué es _.

+0

Sí, puede, porque el argumento es Int => T. Scalac sabe que en el caso de 'alfa', ¿por qué no lo sabe en el caso de' beta'? –

+0

Porque 'beta' está sobrecargado, y hay dos opciones, una de las cuales toma' Int => T' y otra que toma '=> T'. Es por eso que es imposible saber a cuál de estos se refiere sin decirlo explícitamente. Alpha funciona exactamente porque solo hay una opción. – rafalotufo

+4

Eso no es verdad. Es un defecto que es el resultado de tener un parámetro de tipo. No hay ambigüedad si llamo al thunk o la versión de la función si el método no es genérico. He editado la pregunta para mostrar esto. –

Cuestiones relacionadas