1

如果 Scala 也有子类型,那么 Scala 中存在存在主义有什么有意义的理由吗?

例如,在 Haskell 中,existentials 可以用于异构列表,但在 Scala 中,异构列表可以通过使用子类型来创建。

这让我想知道如果 Scala 中有子类型,为什么会有人想要使用存在主义?是否存在无法通过子类型更方便地解决的存在的用例?我不确定是否有。有反例吗?

编辑: Existentials 对于定义更高种类的类型(Functor、Monad 等)很有用,我理解,但除此之外,还有其他有意义的用例吗?

4

3 回答 3

3

我的工作项目中的存在主义示例:

实现类型安全的参数存储

trait Parameter[T] // T is a type of a value related to this parameter

trait ParameterStorage {
   def getValue[T](p: Parameter[T]): Option[T]
}

//implementation
type ParamAndValue = (Parameter[T], T) forSome { type T; }

//initialize storage with pairs of parameters and values
class StorageImpl(pairs: ParamAndValue*) { 
   ...
}
于 2017-05-05T20:28:45.003 回答
2

Consider e.g. Array[_]. It isn't at all the same as Array[Any], e.g.

val x: Array[Any] = new Array[Any](5)
x(0) = "" // legal
val y: Array[_] = new Array[Double](5)
y(0) = "" // illegal

EDIT: Existentials are useful for defining higher kinded types (Functor, Monad, etc), that I understand, but besides them, is there any other meaningful use case ?

No. F[_] in Functor[F[_]] looks the same as an existential, but isn't one at all.

于 2017-05-05T19:07:54.847 回答
0

这是一个刚刚出现的例子:

object Test{
  trait Entity
  case class SEntity() extends Entity
  case class RefVal[T<:Entity](a:T)
  def g(o:RefVal[Entity])= ???
  def g2(o:RefVal[_<:Entity])= ???
  g(RefVal[SEntity](a=SEntity())) // does not compile
  g2(RefVal[SEntity](a=SEntity())) // does compile

}

如果我想避免使 RefVal 协变,那么我需要在这里使用存在主义。

换句话说,existentials 对于以更细粒度的分辨率设置协方差很有用,例如在方法级别上,如上所示,而不是通过将 RefVal 协变量声明为全局设置它RefVal[+T<:Entity]

编辑2:

下面是一些其他有用的existentials用法:

object Existentials_List extends App {

  class A[T]

  class J

  class C1() extends J

  class C2() extends J

  class Z

  val l: Set[A[_ <: J]] = Set()

  val l2: Set[A[_ <: J]] = l + new A[J]   
  val l3: Set[A[_ <: J]] = l + new A[C1]   
  val l4: Set[A[_ <: J]] = l + new A[Z] // does not compile

}

其他可能性是制作 class A[+T]并只是做Set[A[J]],但这会使很多事情变得混乱,协变 + 注释可以感染大部分代码,而这些协变的东西根本不重要。因此,保持事物不变并在一个地方(在存储对象的集合中)使用存在可能是一种比使用协方差注释乱扔代码更简单的解决方案。

于 2017-05-09T04:47:01.317 回答