2014-07-16 13 views
7

staram się zmniejszyć ten kod (scalaz 7.0.x, scala 2.10.x):nie mógł znaleźć ukrytą wartość parametru dowodach typu scalaz.Applicative

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

w tym:

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

i mam błąd "nie można odnaleźć ukrytą wartość parametru dowodach typu scalaz.Applicative [Main.Result]" dla:

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

Dlaczego zredukowany kod nie wygląda jak pierwszy przykład skalaka?

+4

Wygląda na to, że widzisz [tego błędu] (https://issues.scala-lang.org/browse/SI-6895) (chociaż mógłbym przysiąc, że napisałem dokładnie ten kod wcześniej). –

Odpowiedz

3

Niejawna rozdzielczość typów lambda wydaje się zepsuta. Najwyraźniej kompilator najpierw odrzuca typ, a następnie niedopasowuje liczbę parametrów typu.

to 'uproszczony' Przykład:

Definiowanie monady i dwie cechy. One jest podobna do Either. Two jest podobna do 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] = ??? 
} 

Definiowanie aliasu typu oraz klasę przypadku częściowego zastosowania One z String jak to pierwszy parametr. Wersja tego rozwiązania może być używana jako obejście tego problemu.

type OneX[A] = One[String, A] 
case class OneY[A](value: OneX[A]) 
object OneY { 
    implicit def m(implicit ev: Monad[OneX]): Monad[OneY] = ??? 
} 

Niejawne rozwiązanie wszystkich "prostych" typów działa.

implicitly[Monad[OneX]] 
implicitly[Monad[({ type T[x] = One[String, x] })#T]] 
implicitly[Monad[OneY]] 

Definiowanie kilka aliasów typu, które częściowo odnoszą 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] 

Tutaj widzimy, że ktoś przy użyciu typu lambda zawiedzie.

implicitly[Monad[TwoX]] 
implicitly[Monad[TwoY]] // fails 
implicitly[Monad[TwoZ]] 

Tutaj widzimy, że wszystkie typy lambda, które używają aliasu typu fail. Tylko ten, który rzeczywiście odnosi się do typu stabilnego z pojedynczym parametrem, kończy się sukcesem.

implicitly[Monad[({ type T[x] = Two[OneX, x] })#T]] // fails 
implicitly[Monad[({ type T[x] = Two[OneY, x] })#T]] 
implicitly[Monad[({ type T[x] = Two[({ type T[x] = One[String, x] })#T, x] })#T]] //fails 

Moja wiedza na temat kompilatora jest dość ograniczona i może być związana z błędem @ Punkty TravisBrown do.

Powiązane problemy