2011-08-24 13 views
14

Diciamo che avete il seguente:Scala, currying e sovraccarico

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

Scala non consente tale espressione. Per quanto posso vedere, la ragione di questo è che foo ("asdf") non ha un tipo ben definito (è Int => Int o Double => Int).

C'è una ragione per cui tali funzioni "polifere" non dovrebbero essere consentite?

+0

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

+0

Scala consente di definire quella coppia di metodi sovraccaricati, ma ogni chiamata è ambigua, per ragioni illustrate da Martin di seguito. Rilevante: http://stackoverflow.com/questions/2510108/why-avoid-method-overloading – retronym

risposta

19

La risoluzione di sovraccarico in Scala tiene conto solo del primo elenco di parametri. Ecco perché le alternative devono differire già in questa lista. C'è una buona ragione per questo: possiamo quindi usare il tipo di funzione risolta per dedurre il tipo di argomenti successivi. Ciò consente idiomi come:

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

Si noti che qui abbiamo bisogno di conoscere il tipo di corresponds al fine di dedurre il tipo di x e y. Sarebbe un peccato se si verificasse questo guasto quando lo corresponds è sovraccarico.

+0

Grazie per la risposta. Come follow-up, non sarebbe possibile avere una lista di possibili tipi che possono essere assegnati a x e y, in base a quali versioni sovraccariche di corrispondenze sono in ambito (simile a come funzionano gli impliciti) e basta decidere tipi solo quando devi? O questo va contro l'idea della tipizzazione statica? –

+0

@Martin Odersky Puoi vedere http://stackoverflow.com/q/7291168 Grazie! –

+2

Qualsiasi approccio che consideri elenchi di tipi possibili rischia un'esplosione esponenziale dei tempi di controllo dei tipi. Ecco perché Scala generalmente non lo fa nel suo algoritmo di inferenza di tipo. –

2

Questa non è la prima volta che questo è stato chiesto: it was asked back in 2009. Sfortunatamente, Martin non ha dichiarato esplicitamente quali fossero i problemi, a parte il fatto che avrebbe richiesto un cambiamento delle specifiche piuttosto esteso su come funziona il sovraccarico. Ho esaminato le specifiche e non mi è chiaro quali siano i problemi principali, ma non sono abbastanza esperto nelle specifiche per dare una risposta definitiva in entrambi i casi.

+1

Questo è un problema leggermente diverso. Nella domanda a cui ci si collega, si hanno due funzioni, che differirebbero solo nei tipi di ritorno ('pippo (x: Bar): Unit' vs.' pippo (x: Barra): Funzione1 [Bar => Baz, Unità] ') se il mio ragionamento è corretto (ancora non del tutto convinto ...) – Dirk

+0

Non vedo perché il _issue_ è diverso. Le condizioni in cui si manifesta il problema potrebbero essere diverse ma penso che il problema sia lo stesso. Ho provato tutti i tipi di manipolazioni ma l'errore non cambia mai. L'ho letto come, l'overloading è fatto molto presto, o ha la precedenza su "x". –

+0

Non sono sicuro che sia lo stesso. Nel problema scala a cui ti sei collegato, avrebbe senso avere le due funzioni, dato che foo() e foo() _ sono differenti, mentre nella situazione attuale, non ci sono modi diversi per esprimere i due possibili pippo() _ funzioni. La ragione di fondo potrebbe essere la stessa, ma non ne sono convinto. Penso che sia stato anche il punto di Dirk, in realtà. –

Problemi correlati