と仮定「最も具体的な」入力タイプを取得します。私は関数のようなタイプがあり、例えば
trait Parser[-Context, +Out]
と私は組み合わせContext
を組み合わせたパーサ文脈の中で最も固有の型になりますよう複数のパーサを組み合わせることができるようにしたいです。たとえば:
Parser[Any, Int] + Parser[String, Long] = Parser[String, (Int, Long)]
Parser[String, Int] + Parser[Any, Long] = Parser[String, (Int, Long)]
Parser[Option[Int], Foo] + Parser[Some[Int], Bar] = Parser[Some[Int], (Foo, Bar)]
Parser[String, Foo] + Parser[Int, Bar] = <should be a compile error>
は、より具体的に例を置くために、私は今、私は
を行うことができますval f1 = { a: Any => 123 }
val f2 = { a: String => 123 }
val f3 = { a: Option[Int] => 123 }
よう
def zipFuncs[A, B1, B2](f1: A => B1, f2: A => B2): A => (B1, B2) = {
a => (f1(a), f2(a))
}
のような関数合成といくつかの機能を持っていると仮定
> zipFuncs(f1, f2)
res1: String => (Int, Int) = <function>
> zipFuncs(f1, f3)
res2: Option[Int] => (Int, Int) = <function>
> zipFuncs(f2, f3)
res3: Option[Int] with String => (Int, Int) = <function1>
B私が望むのは、zipFuncs(f2, f3)
がまったくコンパイルされないということです。 String
がOption[Int]
のサブタイプではなく、Option[Int]
はString
のサブタイプではないので、res3
の入力値を構築する方法はありません。
私は型クラスを作成しました:
// this says type `T` is the most specific type between `T1` and `T2`
sealed trait MostSpecificType[T, T1, T2] extends (T => (T1, T2))
// implementation of `object MostSpecificType` omitted
def zipFuncs[A, A1, A2, B1, B2](f1: A1 => B1, f2: A2 => B2)(
implicit mst: MostSpecificType[A, A1, A2]
): A => (B1, B2) = { a: A =>
val (a1, a2) = mst(a)
f1(a1) -> f2(a2)
}
これは、上記の目標を達成し、本当に厄介な問題で。 IntelliJは有効な組み合わせをエラーとして強調表示し、実際には実際の値である場合、「最も特定のタイプ(A
)」が実際にはNothing
であると推測します。 Here's the actual issue in practice。
ハイライトの問題は、(それがなかった)確実にIntelliJのではバグであり、Googleの検索は、さまざまなリセット/キャッシュは、/ etcワイプすることを暗示しているようだ、それを修正する必要があります。その責任にかかわらず、私は元の要件を満たし、IntelliJを混乱させることのない別のアプローチを見つけることを望んでいます。
それはまさに私が探していた行動。私は実際のプロジェクトでこのアプローチを試してみる必要があります! – Dylan