La risoluzione implicita dei tipi di lambda sembra interrotta. Apparentemente il compilatore prima desugars il tipo e quindi disallinea sul numero di parametri di tipo.
A 'semplificata' esempio:
Definire una monade e due tratti. One
è simile a Either
. Two
è simile a EitherT
trait Monad[F[_]]
trait One[A, B]
object One {
implicit def m[A]: Monad[({ type T[x] = One[A, x] })#T] = ???
}
trait Two[F[_], A]
object Two {
implicit def m[F[_]]: Monad[({ type T[x] = Two[F, x] })#T] = ???
}
Definire un tipo alias e una classe case di applicare parzialmente One
con String
come è primo parametro. La versione case class può essere utilizzata come soluzione alternativa.
type OneX[A] = One[String, A]
case class OneY[A](value: OneX[A])
object OneY {
implicit def m(implicit ev: Monad[OneX]): Monad[OneY] = ???
}
La risoluzione implicita di tutti i tipi 'semplici' funziona.
implicitly[Monad[OneX]]
implicitly[Monad[({ type T[x] = One[String, x] })#T]]
implicitly[Monad[OneY]]
Definizione dei diversi tipi alias che si applicano in parte Two
type TwoX[A] = Two[OneX, A]
type TwoY[A] = Two[({ type T[x] = One[String, x] })#T, A]
type TwoZ[A] = Two[OneY, A]
Qui vediamo che quella che utilizza il tipo di lambda fallisce.
implicitly[Monad[TwoX]]
implicitly[Monad[TwoY]] // fails
implicitly[Monad[TwoZ]]
Qui vediamo che tutti i tipi di lambda che usano un alias di tipo falliscono. Solo quello che in realtà si riferisce a un tipo stabile con un singolo parametro ha esito positivo.
Le mie conoscenze sul compilatore sono abbastanza limitate e questo potrebbe essere correlato al bug @TravisBrown punta a.
Sembra molto probabile che tu stia vedendo [questo bug] (https://issues.scala-lang.org/browse/SI-6895) (anche se avrei giurato di aver scritto esattamente questo codice prima). –