2016-07-12 11 views
0

私は、最小限の例を作成しようとしました、xは以下のコードにコンパイルされません。どのように暗黙的に型平等を証明する?

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! 
} 

私は(日食で)取得していますエラーは次のとおりです。

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の」何にも依存しない。 Bar & BazFooに依存しますが、Batという文脈を除き、お互いを知りません。

にはどうすればBatのそのQukパラメータを確実にするために、コンストラクタとBazパラメータが同じFooタイプの両方を持ってもらうことができますか?

私はScala 2.11.8を使用しています。

答えて

1

あなたはAuxタイプエイリアスBarのためのトリックとその依存タイプfoo使用することができます、次のように今、あなたはBatを定義することができます

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

    // BarOne ... 
} 

を:

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

あなたの例では、今コンパイル:

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

私はこれをupvoteできますしたい もっと。より詳細な説明は次のとおりです:http://gigiigig.github.io/posts/2015/09/13/aux-pattern.html – muhuk

関連する問題