2011-06-23 9 views
7

Sto avendo un problema nella mia DSL con metodi generici overload conseguente compilatore me che vogliono aggiungere tipi di parametri espliciti:"Missing tipo di parametro" nel metodo generico sovraccarica di prendere un argomento di funzione

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. 

Qualsiasi possibilità che può sbarazzarsi del disordine nell'ultima riga?

EDIT:

Per dimostrare che il sovraccarico non è un problema di ambiguità scalac di per sé, ecco una versione senza parametro di tipo che funziona perfettamente bene:

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

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

risposta

4

Il problema è che Int => T è anche un tipo. Ad esempio, dire che hai definito solo la seconda beta:

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

E ora si passa una funzione Int => Int ad esso:

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

Quindi, dato che una funzione adatta => T, e che anche avere un Int => T, come si suppone che Scala sappia quale si desidera? Potrebbe essere un String, per esempio:

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

Come potrebbe assumere Scala era un Int? Gli esempi che hai dimostrato di dimostrare che il sovraccarico non è da biasimare non dimostrano nulla del genere, perché ti sei sbarazzato dei parametri del tipo al loro interno.

1

Come si potrebbe avere realizzato, il problema si verifica perché la funzione beta è sovraccaricata. Quando si definisce:

beta { _ + 22 } 

cui beta vi aspettate che chiami? Scala non può sapere che _ è un Int solo perché lo stai sommando con 22. Quindi, per questo particolare esempio, devi definire cosa sia _.

+0

Sì, perché l'argomento è Int => T. Scalac sa che nel caso di 'alpha', perché non lo riconosce nel caso di' beta'? –

+0

Poiché 'beta' è sovraccarico, e ci sono due scelte, una delle quali richiede' Int => T' e un'altra che richiede '=> T'. Ecco perché è impossibile dire a quale di questi ti riferisci senza dirlo esplicitamente. Alpha funziona esattamente perché c'è una sola scelta. – rafalotufo

+4

Questo non è vero. È un difetto derivante dall'avere un parametro di tipo. Non c'è alcuna ambiguità se chiamo il thunk o la versione della funzione se il metodo non è generico. Ho modificato la domanda per mostrarlo. –