2015-03-19 13 views
5

dato qualche metodoL'ordine dei parametri impliciti è importante in Scala?

def f[A,B](p: A)(implicit a: X[A,B], b: Y[B]) 

Fa l'ordine di a prima b all'interno della lista questione parametro implicito per inferenza di tipo?

Ho pensato che solo il posizionamento di parametri all'interno di diversi elenchi di parametri è importante, ad es. digitare le informazioni scorre solo attraverso gli elenchi di parametri da sinistra a destra.

Mi chiedo perché ho notato che cambiando l'ordine dei parametri impliciti all'interno dell'elenco implicitamente singolo ha fatto compilare un programma di mia compilazione.

esempio reale

il seguente codice sta usando:

  • informe 2.1.0
  • Scala 2.11.5

Ecco un semplice file SBT build per aiutare insieme compilando gli esempi:

scalaVersion := "2.11.5" 

libraryDependencies += "com.chuusai" %% "shapeless" % "2.1.0" 

scalaSource in Compile := baseDirectory.value 

Sull'esempio. Questo codice viene compilato:

import shapeless._ 
import shapeless.ops.hlist.Comapped 

class Foo { 
    trait NN 
    trait Node[X] extends NN 
    object Computation { 
    def foo[LN <: HList, N <: HList, TupN <: Product, FunDT] 
    (dependencies: TupN) 
    (computation: FunDT) 
    (implicit tupToHlist: Generic.Aux[TupN, LN], unwrap: Comapped.Aux[LN, Node, N]) = ??? 
// (implicit unwrap: Comapped.Aux[LN, Node, N], tupToHlist: Generic.Aux[TupN, LN]) = ??? 

    val ni: Node[Int] = ??? 
    val ns: Node[String] = ??? 
    val x = foo((ni,ns))((i: Int, s: String) => s + i.toString) 
    } 
} 

e questo codice non riesce

import shapeless._ 
import shapeless.ops.hlist.Comapped 

class Foo { 
    trait NN 
    trait Node[X] extends NN 
    object Computation { 
    def foo[LN <: HList, N <: HList, TupN <: Product, FunDT] 
    (dependencies: TupN) 
    (computation: FunDT) 
// (implicit tupToHlist: Generic.Aux[TupN, LN], unwrap: Comapped.Aux[LN, Node, N]) = ??? 
    (implicit unwrap: Comapped.Aux[LN, Node, N], tupToHlist: Generic.Aux[TupN, LN]) = ??? 

    val ni: Node[Int] = ??? 
    val ns: Node[String] = ??? 
    val x = foo((ni,ns))((i: Int, s: String) => s + i.toString) 
    } 
} 

con il seguente errore di compilazione

Error:(22, 25) ambiguous implicit values: 
both method hnilComapped in object Comapped of type [F[_]]=> shapeless.ops.hlist.Comapped.Aux[shapeless.HNil,F,shapeless.HNil] 
and method hlistComapped in object Comapped of type [H, T <: shapeless.HList, F[_]](implicit mt: shapeless.ops.hlist.Comapped[T,F])shapeless.ops.hlist.Comapped.Aux[shapeless.::[F[H],T],F,shapeless.::[H,mt.Out]] 
match expected type shapeless.ops.hlist.Comapped.Aux[LN,Foo.this.Node,N] 
    val x = foo((ni,ns))((i: Int, s: String) => s + i.toString) 
         ^
Error:(22, 25) could not find implicit value for parameter unwrap: shapeless.ops.hlist.Comapped.Aux[LN,Foo.this.Node,N] 
    val x = foo((ni,ns))((i: Int, s: String) => s + i.toString) 
         ^
Error:(22, 25) not enough arguments for method foo: (implicit unwrap: shapeless.ops.hlist.Comapped.Aux[LN,Foo.this.Node,N], implicit tupToHlist: shapeless.Generic.Aux[(Foo.this.Node[Int], Foo.this.Node[String]),LN])Nothing. 
Unspecified value parameters unwrap, tupToHlist. 
    val x = foo((ni,ns))((i: Int, s: String) => s + i.toString) 
         ^
+0

L'ordine non dovrebbe avere importanza, almeno in isolamento. Tuttavia, cambiando l'ordine dell'implicito cambia definitivamente la firma del metodo, quindi cambia il tipo di classe/tratto in cui è definito. In ogni wase, devi sicuramente pubblicare un frammento di codice che mostri come cambiare l'ordine cambia il risultato della compilazione, altrimenti è difficile discutere del problema. –

+0

@ RégisJean-Gilles Ho aggiunto un piccolo esempio. – ziggystar

risposta

1

In base alla mia lettura dei commenti di the issue menzionati da Lorand Szakacs, giungo alla conclusione che l'ordine dei parametri impliciti è importante nella versione corrente 2.11 del compilatore Scala.

Questo perché gli sviluppatori che partecipano alla discussione sembrano presumere che l'ordine contenga; non lo dichiarano esplicitamente.

Non sono a conoscenza delle specifiche della lingua che menzionano nulla su questo argomento.

0

Riordinamento li solo rompere il codice che li passa in modo esplicito, così come tutte compilate codice. Tutto il resto non sarà interessato.

+0

Si prega di vedere il mio esempio. – ziggystar

2
  1. Normalmente non dovrebbe importare. Se si guarda allo language spec, non si fa alcun accenno al fatto che la risoluzione dipenda dall'ordine dei parametri.

  2. Ho guardato il codice sorgente di informe, e non sono riuscito a trovare alcun motivo per cui questo errore si sarebbe presentato.

  3. E facendo una rapida ricerca attraverso il repository di bug della lingua ho trovato un similar issue apparentemente risolto. Ma non indica se la correzione coinvolto trattare il sintomo (rendendo limiti di contesto non si rompono compilazione) o la causa (restrizioni al parametro implicito ordinazione.)

Perciò direi che si tratta di un bug del compilatore, e è strettamente correlato al problema legato al punto 3.

Inoltre, vorrei suggerire di inviare una segnalazione di errore se si può trovare un secondo parere che il risultato di un'analisi più rigorosa della mia :)

Speranza questo ti fa riposare la mente. Saluti!

+2

Ho letto i commenti al problema, e sembra che tutti i commentatori implicitamente presumano che l'ordine dei parametri impliciti sia importante. – ziggystar

Problemi correlati