2014-07-16 18 views
7

Sto cercando di ridurre questo codice (scalaz 7.0.x, scala 2.10.x):non riusciva a trovare valore implicito per il parametro prove di tipo scalaz.Applicative

type Error[+A] = \/[String, A] 
type Result[+A] = OptionT[Error, A] 

in questo:

type Result[+A] = OptionT[({ type λ[+α] = String \/ α })#λ, A] 

ed ho ottenuto l'errore "Impossibile trovare il valore implicito per il parametro prove di tipo scalaz.Applicative [Main.Result]" per:

val result: Result[Int] = 42.point[Result] 

Perché codice ridotto non sembra il primo esempio di scalac?

+4

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). –

risposta

3

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.

Problemi correlati