当我有这样的通用类时
case class C [E] (errors : Seq[E]){
def merge [E1 <: EX, EX >: E] (errors1 : Seq[E1]) = Seq[EX]() ++ errors ++ errors1
}
一切正常 - 它将错误序列合并为一系列常见的超类型。但是当我将它与类型类模式混合时,它并没有正确地推断出常见的超类型。
我已经根据this approach实现了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容器是这样的(我可以使用Either但不应该相关)
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,因此找不到应用程序。推理可以修复吗?是否有关于推理的规则的材料?我找不到任何规范。