“放置”的意义是什么;forSome“;Scala泛型语法中的子句?
根据对的回答,似乎将“forSome”放在类型定义的某个组件之后不同于将其放在整个事件的末尾。例如,以下各项之间似乎存在差异:“放置”的意义是什么;forSome“;Scala泛型语法中的子句?,scala,existential-type,Scala,Existential Type,根据对的回答,似乎将“forSome”放在类型定义的某个组件之后不同于将其放在整个事件的末尾。例如,以下各项之间似乎存在差异: def one: Foo[U >: T] forSome {type U >: T} def one: Foo[U forSome {type U >: T}] scala> val xs: Set[X] forSome { type X } = Set[Int](1, 2, 3) xs: Set[_] = Set(1, 2, 3) Sca
def one: Foo[U >: T] forSome {type U >: T}
def one: Foo[U forSome {type U >: T}]
scala> val xs: Set[X] forSome { type X } = Set[Int](1, 2, 3)
xs: Set[_] = Set(1, 2, 3)
Scala语言规范似乎没有说明任何区别,我可以想象,将量词移到外部不会有任何区别。如果它确实有区别,我会认为它会如中所述,基本上说Set[X对于某些{type X}]允许X在集合元素之间变化,而Set[X]对于某些{type X}则不允许。然而,这似乎不是全部,并且/或者是不正确的,因为这并不编译:
trait Bar {
def test: Set[X] forSome {type X}
}
def test(b: Bar) {
val set = b.test
val h = set.head
set.contains(h)
}
scala> val xs: Set[X forSome { type X }] = Set[Int](1, 2, 3)
<console>:7: error: type mismatch;
found : scala.collection.immutable.Set[Int]
required: Set[X forSome { type X }]
Note: Int <: X forSome { type X }, but trait Set is invariant in type A.
但这确实:
trait Bar {
def test: Set[X forSome {type X}]
}
def test(b: Bar) {
val set = b.test
val h = set.head
set.contains(h)
}
似乎Set[X]forSome{type X}为实例化类中的每个使用站点创建了一个单独的抽象类型,其中Set[X forSome{type X}只创建一个抽象类型并将其用于整个类。这与我的预期相反,似乎与上面提到的答案不一致 首先有几个观察结果:
X对于某些{type X}
只是一种编写Any
的奇特方式-这是一种我们一无所知的类型,因此它必须位于类型层次结构的顶部。如果您不相信我,请询问编译器:
scala> implicitly[Any =:= X forSome { type X }]
res0: =:=[Any, _] = <function1>
这里我们已经说过,xs
是一组特定类型的X
,但是我们马上就会忘记关于X
的一切。请注意,与上面的xs
定义不同,这是可以编译的,因为我们并不是说xs
是一组任何东西,只是它是一组我们不知道的特定类型(或者说编译器不知道)
这意味着绝对不可能有a
使xs.contains(a)
编译。让我们试试一个明显的例子:
scala> xs.contains(1)
<console>:9: error: type mismatch;
found : Int(1)
required: X
xs.contains(1)
^
这也不会编译,并显示以下消息:
found : (some other)X(in method test) where type (some other)X(in method test)
required: X(in method test) where type X(in method test)
def test(b: Bar) = b.test.contains(b.test.head)
^
也就是说,即使我们刚刚从
b.test
中提取了b.test.head
,我们仍然无法对其应用b.test.contains
。我们已经告诉编译器,它只知道b.test
的项类型存在,所以它不会跟踪这样一个事实,即b.test.head
是我们应该能够应用b.test.contains
的一种东西。这至少可以澄清一点情况@Andrey-这很有趣,特别是因为这个问题的公认答案意味着语义与我认为我看到的相反。@Andrey-事实上,我想进一步说,这个问题的公认答案作为这个问题的答案是没有用的,可能是完全错误的。请参阅上面我修改过的示例。上的最后一个代码块解释了差异。我想你的第一个是所有的集合,第二个是所有的集合。谢谢,这很有意义。
found : (some other)X(in method test) where type (some other)X(in method test)
required: X(in method test) where type X(in method test)
def test(b: Bar) = b.test.contains(b.test.head)
^