假设我有类似功能的类型,例如获取“最具体”的输入类型
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>
投入更多具体而言例如,假设我有一个函数组合像
def zipFuncs[A, B1, B2](f1: A => B1, f2: A => B2): A => (B1, B2) = {
a => (f1(a), f2(a))
}
和一些功能,如
val f1 = { a: Any => 123 }
val f2 = { a: String => 123 }
val f3 = { a: Option[Int] => 123 }
现在我能做的
> 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 ut我想要的是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中的一个错误,谷歌搜索似乎意味着各种重置/缓存抹布/等应该修复它(它没有)。无论责备什么,我都希望找到一种既能满足我原来的要求,又不会混淆IntelliJ的替代方法。
这就是我一直在寻找的行为。我将不得不在我的实际项目中尝试这种方法! – Dylan