【发布时间】:2016-03-12 18:18:11
【问题描述】:
有时 Scala 难以推断类型。这里的目标是了解原因并尝试帮助 Scala 进行更好的推理。
用一个简单的例子可以更好地解释这个问题:
trait A
trait B
class G[Ao <: A, Bo <: B](a: Ao, b: Bo)
// This is my "complex" class with 3 type parameters
class X[Ao <: A, Bo <: B, Go <: G[Ao,Bo]](a: Ao, b: Bo, g: Go)
val a = new A{}
val b = new B{}
val g = new G(a,b)
下面的 OO 类型完美推断:
class OO extends X(a,b,g) // Type of X[A,B,G[A,B]]
但是,如果我们将其中一个参数更改为一个选项(或任何集合),并且我们提供一个空集合(或 None),那么推理将不起作用。
case class X[Ao <: A, Bo <: B, Go <: G[Ao,Bo]](a: Ao, b: List[Bo], g: Go)
class OO extends X(a,List(),g)
<console>:XX: error: inferred type arguments [A,Nothing,G[A,B]] do not conform to class X's type parameter bounds [Ao <: A,Bo <: B,Go <: G[Ao,Bo]]
class OO extends X(a,List(),g)
^
<console>:XX: error: type mismatch;
found : A
required: Ao
class OO extends X(a,List(),g)
^
<console>:XX: error: type mismatch;
found : G[A,B]
required: Go
class OO extends X(a,List(),g)
这可以通过像这样显式传递 OO 的所有参数来解决:
class OO extends X[A,B,G[A,B]](a,List(),g)
问题是,G 已经有了它的类型,从 X 的定义中我们看到 G 接受了 X 的前两个参数,所以如果我们知道 G,我们就拥有了推断 X 的参数所需的一切。我可以做一些不同的事情来帮助 Scala 进行推理吗?我有一个类,它的参数比 X 多得多,现在我总是必须明确定义它们。我正在尝试查看是否可以做些什么来帮助 Scala 成功推断类型。
【问题讨论】:
标签: scala type-inference