Scala:对多态类型的单例实例使用 Nothing

标签 scala singleton polymorphism nothing

给定一个多态性状

 trait Transform[T] { def apply( t: T ) : T }

人们可能喜欢实现各种专门的实例,例如

 case class Add[Double] extends Transform[Double] { def apply( t: Double ) ... }
 case class Append[String] extends Transform[String] { def apply( t: String ) ... }

等现在经常需要的变换也是恒等变换。与其为每种类型 T 专门化标识,不如为所有类型 T 使用一个单例实例似乎更可取。我的问题是:在 Scala 中实现这一点的最佳方法是什么?

这是我到目前为止的发现:查看 List[T] 如何实现 List.empty[T] 和 Nil,我尝试使用 Nothing 作为类型 T。这似乎是有道理的,因为 Nothing 是每个类型的子类型其他类型:

 object Identity extends Transform[Nothing] {
    def apply( t: Nothing ) = t
 }

这似乎可行。然而,无论我想在哪里使用这个实例,就像这里一样:

 val array = Array[Transform[String]]( Transform.Identity )

我收到编译器错误“类型不匹配;找到:Identity.type,需要:Transform[String]”。为了使用它,我必须显式地转换它:

 ... Identity.asInstanceOf[Transform[String]]

我不确定这是最好的,甚至是“正确”的方法。感谢您的任何建议。

最佳答案

正如@Kim Stebel 指出您的 Transform[T]T 中不变(而且必须是因为 T 出现在 def apply(t : T) : T) 的同变体和反变体位置,所以 Transform[Nothing] 不是 Transform[String] 的子类型,不能成为。

如果您主要关心的是每次调用 Kim 的 def Id[A] 时创建的实例那么你最好的模型就是 conforms 的定义在预定义中,

private[this] final val singleton_<:< = new <:<[Any,Any] { def apply(x: Any): Any = x }
implicit def conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A]

即。使用多态方法,返回转换为适当类型的单例值。这是删除成功的场合之一。

应用于您的情况我们会,

object SingletonId extends Transform[Any] { def apply(t : Any) = t }
def Id[A] = SingletonId.asInstanceOf[Transform[A]]

示例 REPL session ,

scala> Id("foo")
res0: java.lang.String = foo

scala> Id(23)
res1: Int = 23

关于Scala:对多态类型的单例实例使用 Nothing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7631478/

相关文章:

performance - Scala 中的抽象类真的比特征表现更好吗?

scala - map 合并功能的改进

定义接受不同数字类型列表的函数的 Scala 方法

c++ - C++ 中的命名空间冲突

java - 我如何在java中表现出强制(一种临时多态行为)?

scala.collection.JavaConversions API : Where is the asScala method?

c++私有(private)属性可以在构造函数中使用,但在其他方法中会出现段错误

wpf - 绑定(bind)到单例类可观察集合成员

java - 实现在应用程序启动时而不是在编译时初始化的 "constants"类

ruby-on-rails - 单表继承(Rai​​ls)的一对多关系问题