Scala 中的多个类型下限
我注意到 tuple.productIterator 总是返回一个 Iterator[Any] ,想知道是否无法设置多个下限(因此它可能是最低公共超级的迭代器)类型)。
我尝试并搜索了一下,但只找到了 这个 多个上限的问题。
这是我对如何定义迭代器类型的测试:
def f[A,B](a:A, b:B) = List(a,b)
// return type is List[Any]
def f[A,B, T >: A "and" T >: B](a:A, b:B) = List[T](a,b)
// doesn't compile, but
// f(1, true) should give a List[AnyVal] and
// f("x", "y") a List[String]
这是 JVM 的限制吗?
Edit: Here's a slightly bigger example which doesn't seem to be solvable using IttayD approach when T should be defined in the method:
class Foo[A, B](a: A, b: B) {
def f[T >: A] = List[T](a) // works
def g[T >: A "and" T >: B] = List[T](a) // doesn't work
}
I noticed that tuple.productIterator
always returns an Iterator[Any]
an wondered if it's not possible to set multiple lower bounds (so it could be an Iterator of the lowest common super type).
I tried and searched a bit, but only found this question for multiple upper bounds.
This is my test on how to define the the type of the iterator:
def f[A,B](a:A, b:B) = List(a,b)
// return type is List[Any]
def f[A,B, T >: A "and" T >: B](a:A, b:B) = List[T](a,b)
// doesn't compile, but
// f(1, true) should give a List[AnyVal] and
// f("x", "y") a List[String]
Is this a limitation of the JVM?
Edit:
Here's a slightly bigger example which doesn't seem to be solvable using IttayD approach when T should be defined in the method:
class Foo[A, B](a: A, b: B) {
def f[T >: A] = List[T](a) // works
def g[T >: A "and" T >: B] = List[T](a) // doesn't work
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于
A
和B
与T
同时被编译器绑定的简单情况,IttayD 的答案工作正常:当
A
和B
已经绑定在您的class Foo[A, B]
示例中,您需要引入临时虚拟变量来让编译器完成这项工作:(For为了清楚起见:
A1 >: A <: T
表示类型A1
必须是A
的超类型和A
的子类型code>T,而不是那个A
是A1
和T
的子类型。)A1
和B1< /code> 在这里的唯一目的是推断
T
的正确类型。如果编译器必须推断它们,它们将解析为A1 = A
和B1 = B
,然后将T
作为最具体的类型是A
和B
的超类。然而,编译器没有意识到的一件事是,通过传递性,我们同时拥有
T >: A
和T >: B
,它直接跟随来自关于A1
和B1
的约束。我们需要帮助解决类型归属问题。现在,
Product#productIterator
无法使用此技术,因为它是在我们甚至不知道A
和B
的地方定义的,或者具体子类中确实有多少个类型参数。For the simple case where
A
andB
are bound by the compiler as the same time asT
, IttayD's answer works fine:When
A
andB
are already bound as in yourclass Foo[A, B]
example, you need to introduce temporary dummy variables to have the compiler do this job:(For the sake of clarity:
A1 >: A <: T
means that typeA1
must be a supertype ofA
and a subtype ofT
, and not thatA
is a subtype of bothA1
andT
.)A1
andB1
are here for the sole purpose of inferring a correct type forT
. If the compiler has to infer them, they will resolve toA1 = A
andB1 = B
, and thenT
as the most specific type which is a superclass of bothA
andB
.One thing that the compiler doesn't realize, though, is that, by transitivity, we have both
T >: A
andT >: B
, which follows directly from the constraints with respect toA1
andB1
. We need to help out with the type ascriptions.Now,
Product#productIterator
could not use this technique, as it's defined in a place where we don't even knowA
andB
, or indeed how many type parameters there are in the concrete subclass.听起来你需要的是一个 HList: http://apocalisp.wordpress.com/2010/07/06/type-level-programming-in-scala-part-6a-heterogeneous-list%C2%A0basics/
回答具体问题:
It sounds like what you need is an HList: http://apocalisp.wordpress.com/2010/07/06/type-level-programming-in-scala-part-6a-heterogeneous-list%C2%A0basics/
To answer the specific question: