让我们来看一个例子(这是一个天真的例子,但足以说明问题)。根据输入参数返回不同类型
def produce(l: List[Int]) : Any =
l match {
case List(x) => x
case List(x, y) => (x, y)
}
val client1 : Int = produce(List(1)).asInstanceOf[Int]
缺点:客户端需要投!
def produce2[A](l: List[Int])(f: List[Int] => A) = {
f(l)
}
val toOne = (l: List[Int]) => l.head
val toTwo = (l: List[Int]) => (l.head, l.tail.head)
val client2 : Int = produce2(List(1))(toOne)
缺点:类型安全性,即我们可以通过一个单例列表调用toTwo。
有没有更好的解决方案?
标准斯卡拉'List'没有抓住它的长度在其类型,所以你不能阻止'从toTwo'被称为列表元素太少的列表。使用“HList”(例如无形),可以做到这一点,因为每个元素的类型(因此也就是内在的长度)是静态已知的。如果我真的知道如何编写特定的代码,我会做出这个答案,但是我对Shapeless和'HList'的了解只是“理论上的”。无形:https://github.com/milessabin/shapeless –