かなり複雑な型レベルの計算をいくつか試しています。そこには、いくつかの型タグ ( 、A
、B
、および などC
) と、それらに作用する関数があります。これらは、パス依存の結果型を持つ暗黙の監視によって表されます。
class A
class B
class C
trait F1[T] { type result }
trait F2[T] { type result }
implicit object f1OfA extends F1[A] { type result = B }
implicit object f2OfB extends F2[B] { type result = C }
trait Composed[T] { type result }
計算の過程で、「実装」するときComposed
、上記のコードが与えられた場合、原則として変換できるという事実を利用する必要がありますA
(C
この例では、構成が必要なだけですが、実際にはもっと多くのことが関係しています) .
しかし、私は常に Implicit が推移的に適用されないという制限によって制限されているため、構成を表現する方法がわかりません。次のコードは、「暗黙的に見つかりません」で失敗します。
implicit def composed1[X](implicit f2DotF1OfX: F2[F1[X]]): Composed[X] =
new Composed[X] { type result = f2DotF1OfX.result }
implicitly[Composed[C]]
私が実際に最初に書こうとしたのは次のとおりです。
implicit def composed2[X](implicit f1OfX: F1[X], f2OfLast: F2[f1OfX.result]): Composed[X] =
new Composed[X] { type result = f2OfLast.result }
f1OfLast
定義されている同じパラメーターリストで使用したため、これはもちろん失敗しました。暗黙のパラメーターでない場合は、次のように記述できます
implicit def composed3a[X](f1OfX: F1[X])(f2OfLast: F2[f1OfX.result]): Composed[X] =
new Composed[X] { type result = f2OfLast.result }
ただし、2 つの暗黙的なパラメーター リストを使用してこれを行うことはできません。これは、言語で許可されていないためです。
F2[F1[X]]
要するに、上記の例で証人を得るにはどうすればよいですか? 必要に応じて、型レベル関数の書き方を変更することもできますが、それらを表現する別の方法はまだ見つかっていません。