2016-07-12 7 views
0

habe ich versucht, ein minimales Beispiel zu erstellen, x nicht in dem folgenden Code nicht kompiliert:Wie kann man die Typgleichheit gegenüber einem impliziten beweisen?

sealed trait Foo 

case object FooOne extends Foo 

sealed trait Bar[T] { 
    type foo <: Foo 
} 

object Bar { 
    implicit case object BarOne extends Bar[Int] { 
    type foo = FooOne.type 
    } 
} 

case class Quk[B: Bar](b: B) 

sealed trait Baz[F <: Foo] 

case object BazOne extends Baz[FooOne.type] 

case class Bat[B: Bar, F <: Foo](r: Quk[B], z: Baz[F])(implicit ev: Bar[B]#foo =:= F) 

object Bat { 
    val x = Bat(Quk(1), BazOne) // Compilation error here! 
} 

Der Fehler Ich erhalte (in Eclipse) ist:

Cannot prove that com.muhuk.Example.Bar[Int]#foo =:= com.muhuk.Example.FooOne.type. 
not enough arguments for method apply: (implicit evidence$2: com.muhuk.Example.Bar[Int], implicit ev: =:=[com.muhuk.Example.Bar[Int]#foo,com.muhuk.Example.FooOne.type])com.muhuk.Example.Bat[Int,com.muhuk.Example.FooOne.type] in object Bat. Unspecified value parameter ev. 

Foo doesn‘ t hängen von allem ab. Bar & Baz sind abhängig von Foo, aber sie wissen nicht voneinander, außer im Zusammenhang mit Bat.

Wie kann ich Bat ‚s Konstruktor, um sicherzustellen, seine Quk Parameter und Baz Parameter haben beide die gleiche Foo Art bekommen?

Ich benutze Scala 2.11.8.

Antwort

1

könnten Sie verwenden den Aux Typ alias Trick für Bar und seinen abhängigen Typ foo:

object Bar { 
    type Aux[T, F] = Bar[T] { type foo = F } 

    // BarOne ... 
} 

Jetzt können Sie Bat wie folgt definieren:

case class Bat[B, F <: Foo](r: Quk[B], z: Baz[F])(implicit bar: Bar.Aux[B, F]) 

Ihr Beispiel jetzt kompiliert:

val x = Bat(Quk(1), BazOne) 
// x: Bat[Int,FooOne.type] = Bat(Quk(1),BazOne) 
+0

Ich wünschte, ich könnte dies verbessern Mehr. Hier ist eine detailliertere Erklärung: http://gigiigig.github.io/posts/2015/09/13/aux-pattern.html – muhuk

Verwandte Themen