Pimp La mia funzione in Scala - Applicazione delle conversioni implicite sulle funzioni
Domanda
Ho alcuni problemi quando voglio usare metodi impliciti per convertire una funzione a qualcos'altro.
Sto implementazione di una piccola DSL a Scala 2.8 per scopi di test. Dovrebbe supportare vari controlli (asserzioni se ti piace) su istanze. L'intera DSL è un po 'complesso, ma il seguente esempio semplificato mostra il mio problema:
object PimpMyFunction {
class A(val b: Int)
def b(a: A) = a.b
class ZeroCheck(f: A => Int) {
def isZeroIn(a: A) = f(a) == 0
}
implicit def fToCheck(f: A => Int): ZeroCheck = new ZeroCheck(f)
def main(args: Array[String]) {
val a0 = new A(0)
val a1 = new A(1)
println(fToCheck(b).isZeroIn(a0))
println(fToCheck(b).isZeroIn(a1))
println(b.isZeroIn(a0))
}
}
.
Prime due linee di println (quando chiamoso esplicitamente il metodo di conversione) compila e funzionano bene, ma l'ultimo (quando voglio fare affidamento su impliciti) produce l'errore:
Compile error: missing arguments for method b in object PimpMyFunction; follow this method with '_' if you want to treat it as a partially applied function
.
Se voglio implicitamente convertire le istanze "normali" (che non sono funzioni) nello stesso modo in cui funziona anche, quindi immagino che il problema non sia correlato all'incidente / importazione.
Se seguo le istruzioni del messaggio di errore e utilizzare println((b _).isZeroIn(a0))
funziona anche, ma il DSL è mirato a persone non tecniche, quindi vorrei mantenere la sintassi più pulita e semplice possibile.
Penso di avere un'altra soluzione alternativa (B dovrebbe essere una classe che estende un tratto di asserzioni che contiene già i metodi di controllo + A=> int) che supporterebbe la sintassi del pulitore, ma sarebbe più verboso e meno flessibile, quindi io preferirebbe il modo implicito.
Qualche idea come evitare la sintassi (b _)
e utilizzare ancora impliciti?
Soluzione
Scala richiede di scrivere (B _) per assicurarti di voler davvero che il metodo B sia boxed a un valore di funzione.Se non si desidera scrivere il sottolineamento, definire direttamente B per essere un valore di funzione anziché un metodo:
val b = (a: A) => a.b
. Altri suggerimenti
Il problema avviene perché b
non è una funzione, ma un metodo.Si prega di cercare domande correlate su quell'argomento.Se si definisce b
come di seguito, tuttavia, non dovresti avere problemi:
def b = (_: A).b
.
Questo definisce il tipo di b
per essere una funzione.