2011-08-24 20 views
14

Digamos que tiene lo siguiente:Scala, currying y la sobrecarga

foo(x: String)(y: Int): Int 
foo(x: String)(y: Double): Int 

Scala no permite tal expresión. Por lo que puedo ver, la razón de esto es que foo ("asdf") no tiene un tipo bien definido (es Int => Int o Double => Int).

¿Hay alguna razón por la cual no se deberían permitir tales funciones "politipo"?

+0

https://issues.scala-lang.org/browse/SI-2628 – Bradford

+0

Scala le permite definir ese par de métodos sobrecargados, pero cualquier llamada es ambigua, por los motivos descritos por Martin a continuación. Relevante: http://stackoverflow.com/questions/2510108/why-avoid-method-overloading – retronym

Respuesta

19

La resolución de sobrecarga en Scala solo tiene en cuenta la primera lista de parámetros. Es por eso que las alternativas deben diferir ya en esta lista. Hay una buena razón para esto: podemos usar el tipo de función resuelta para inferir el tipo de argumentos posteriores. Esto permite a los idiomas como:

xs.corresponds(ys) { (x, y) => x < y } 

Tenga en cuenta que aquí tenemos que conocer el tipo de corresponds con el fin de inferir los tipos de x y y. Sería una pena tener este problema cuando corresponds está sobrecargado.

+0

Gracias por la respuesta. Como seguimiento, ¿no sería posible tener una lista de tipos posibles que se pueden asignar a xey, en función de qué versiones de correspondencias sobrecargadas están en el alcance (similar a cómo funcionan las implícitas) y simplemente decidir sobre el tipos solo cuando tienes que hacerlo? ¿O esto iría en contra de la idea del tipado estático? –

+0

@Martin Odersky ¿Podría ver http://stackoverflow.com/q/7291168 ¡Gracias! –

+2

Cualquier enfoque que considere listas de tipos posibles corre el riesgo de una explosión exponencial de tiempos de verificación de tipos. Es por eso que Scala generalmente no hace eso en su algoritmo de inferencia tipo. –

2

Esta no es la primera vez que esto se ha preguntado: it was asked back in 2009. Desafortunadamente, Martin no indicó explícitamente cuáles eran los problemas, aparte de eso, requeriría un cambio de especificaciones bastante extenso sobre cómo funciona la sobrecarga. Miré la especificación y no tengo claro dónde están los problemas principales, pero no estoy lo suficientemente capacitado en la especificación para dar una respuesta definitiva en ambos sentidos.

+1

Este es un problema ligeramente diferente. En la pregunta a la que se vincula, tiene dos funciones, que solo se diferenciarían en sus tipos de retorno ('foo (x: Bar): Unit' vs.' foo (x: Bar): Function1 [Bar => Baz, Unit] ') si mi razonamiento es correcto (aún no del todo convencido ...) – Dirk

+0

No veo por qué el _issue_ es diferente. Las condiciones bajo las cuales se manifiesta el problema pueden ser diferentes, pero creo que el problema es el mismo. Intenté todo tipo de manipulaciones, pero el error nunca cambia. Lo leí porque la sobrecarga se hace muy temprano o tiene prioridad sobre "x". –

+0

No estoy seguro de que esto sea lo mismo. En el problema Scala con el que se vinculó, tendría sentido tener las dos funciones, ya que foo() y foo() _ son diferentes, mientras que en la situación actual, no hay formas diferentes de expresar los dos posibles foo() _ funciones. La razón subyacente podría ser la misma, pero no estoy convencido. Creo que ese fue también el punto de Dirk, en realidad. –

Cuestiones relacionadas