Ho uno strano errore del compilatore su un implicito che è effettivamente presente ma non è stato trovato per un motivo. Quindi ho costruito un piccolo test che riproduce comportamenti misteriosi.In alcuni casi, gli impliciti di alto ordine vengono ignorati?
Tipo semplice utilizzato come target non ambiguo per le conversioni implicite.
def id[H <: Hide, C](x : C)(implicit ev : C => H#T) : H#T = ev(x)
def drop[H <: Hide, C](x : C)(implicit ev : C => H#T) : Int = {
println(ev(x))
1
}
def idSeq[H <: Hide, C](x : Seq[C])(implicit ev : Seq[C] => Seq[H#T]) : Seq[H#T] = ev(x)
def dropSeq[H <: Hide, C](x : Seq[C])(implicit ev : Seq[C] => Seq[H#T]) : Int = {
println(ev(x))
1
}
I metodi che si basano su conversioni implicite. È fondamentalmente una matrice 2x2. I metodi id
restituiscono il tipo convertito e i metodi drop
utilizzano la conversione internamente e restituiscono una costante. I metodi normali funzionano sul tipo esattamente convertito implicitamente e i metodi Seq
funzionano su sequenze.
implicit def exString(x : String) : HideString.type#T = x
implicit def highString[F[_]](x : F[String]) : F[HideString.type#T] = x
Sopra conversioni implicite highString
è definito con il tipo di ordine superiore.
val s1 = id("sdf")
val s2 = drop("aero")
val r1 = idSeq(Seq("a", "bc"))
val r2 = dropSeq(Seq("i", "IO"))
Cercando utilizzare effettivamente conversioni mi porta un errore:
ImplicitResolution.scala:98: error: No implicit view available from Seq[String] => Seq[test.implicits.HighReduction.Hide#T].
val r2 = dropSeq(Seq("i", "IO"))
che potrebbe essere riassunto nella seguente matrice:
| | id | drop |
|--------+------+------|
| normal | pass | pass |
| seq | pass | fail |
se uso definito con precisione conversione implicita per dropSeq
metodo si trova normalmente:
implicit def seqBool(x : Seq[Boolean]) : Seq[HideBool.type#T] = x
val a1 = idSeq(Seq(true, false))
val a2 = dropSeq(Seq(false, true))
E inoltre, se a specificare in modo esplicito implicito argomento dropSeq
ha cominciato a lavorare:
val r2i = dropSeq(Seq("i", "IO"))(highString[Seq] _)
E questa è la cosa più strana. highString
implicito soddisfa tutti i requisiti. Ed è dichiarato come implicit
, quindi dovrebbe essere trovato dal compilatore. E in caso di idSeq
è effettivamente trovato. Quindi, perché viene ignorato nel caso dropSeq
?
Sarei più propenso a concederti la taglia se hai archiviato un problema per il "caso angolo nel compilatore Scala" che descrivi. Supponevo che si trattasse di un caso d'angolo, ma non hai ancora fornito informazioni sufficienti per sapere se questo comportamento è * previsto *, o se è davvero un bug nel compilatore. Sarebbe anche bello se ti liberassi di questo '}' ... – DaoWen
Le tue due funzioni hanno la stessa firma ad eccezione del tipo restituito, ma tu usi l'inferenza di tipo per r1 e r2 (quindi il tipo di ritorno non può essere usato per la risoluzione implicita). Se è possibile risolvere l'implicito per r1 con le informazioni sul tipo disponibili, è possibile risolvere l'implicito per r2: dato che drop funziona e dropSeq no, è probabile che il problema sia con le proiezioni di tipo e tipo generici. – Edmondo1984
L'uso di '-Xlog-implicits' restituisce alcuni errori interessanti. –