このようなジェネリック クラスがある場合
case class C [E] (errors : Seq[E]){
def merge [E1 <: EX, EX >: E] (errors1 : Seq[E1]) = Seq[EX]() ++ errors ++ errors1
}
すべてが機能します - エラーのシーケンスを共通のスーパータイプのシーケンスにマージします。ただし、これを型クラス パターンと組み合わせると、共通のスーパータイプが正しく推論されません。
このアプローチに従って HList アプリケーションを実装しましたが、それ自体で動作します。ここで、各引数が失敗する可能性のある引数リストを作成するために使用したいと思います。最後に、この引数リストを、それ自体が失敗する可能性のある関数に適用できるようにしたいと考えています。したがって、出力エラー シーケンス タイプは、リスト エラーおよび関数エラーのスーパータイプである必要があります。(次のステップは、関数が ErrorProne を返さなければならないという制限を解除し、何らかの型クラスを介してフラット化することですが、これはより単純なケースだと思います。) 失敗した引数リスト ラッパーは次のようになります。:: メソッドが機能することに注意してください。
case class SuccessArgList [E, L <: HList[L]] (list : L) extends ArgList[E, L] {
override def apply[S, E1 <: EX, EX >: E, F](fun : F)(implicit app : HApply[L, F, ErrorProne[E1, S]])
: ErrorProne[EX, S] = app.apply(list, fun)
override def :: [A, E1 <: EX, EX >: E] (argument : ErrorProne[E1, A]) : ArgList[EX, A :: L] = argument match {
case Success(a) => SuccessArgList(a :: list)
case Failure(e) => FailureArgList(e)
}
}
ここで、E は現在失敗している引数リストのエラーの型、L は実引数リストの型、S は関数の成功値の型、E1 は関数の失敗値の型、EX はエラーの共通スーパータイプ、F は関数。失敗リストも同様で、ErrorProne コンテナーは次のようになります (おそらくどちらも使用できますが、それは関係ありません)。
sealed trait ErrorProne[+F, +S]{
def f[To] (implicit flatrener : FlattenErrorProne[ErrorProne[F, S], To]) = flatrener.flatten(this)
}
case class Success [+F, +S] (result : S) extends ErrorProne[F, S]
case class Failure [+F, +S] (errors : Seq[F]) extends ErrorProne[F, S]
引数リスト型のapplyメソッドを使おうとすると、E1~Eの判定を間違えて引数が推論されてしまうため、アプリケーションが見つかりません。推論は修正できますか?推論のルールに関する資料はありますか? 仕様が見つかりません。