Pimp La mia funzione in Scala - Applicazione delle conversioni implicite sulle funzioni

StackOverflow https://stackoverflow.com/questions/3288385

  •  17-09-2020
  •  | 
  •  

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?

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top