Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“放置”的意义是什么;forSome“;Scala泛型语法中的子句?_Scala_Existential Type - Fatal编程技术网

“放置”的意义是什么;forSome“;Scala泛型语法中的子句?

“放置”的意义是什么;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

根据对的回答,似乎将“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)
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)
                                             ^