Case对象在Scala中使用构造函数扩展类

时间:2017-06-03 07:39:41

标签: scala functional-programming abstract-data-type

我是Scala的初学者,正在四处寻找有关抽象数据类型的更多信息。我定义了以下定义来复制Option类型:

sealed abstract class Maybe[+A](x:A)
case object Nothing extends Maybe[Nothing](Nothing)
case class Just[A](x:A) extends Maybe[A](x)

但是我遇到了以下错误。

found   : Nothing.type
required: Nothing
    case object Nothing extends Maybe[Nothing](Nothing)

如何通过Nothing代替Nothing.type

我提到了以下问题提示: How to extend an object in Scala with an abstract class with constructor?,但没有帮助。

4 个答案:

答案 0 :(得分:3)

也许更像这样。你什么都不应该有价值,只有类型。人们通常也会使用特征而不是抽象类。

sealed trait Maybe[+A]
case object None extends Maybe[Nothing]
case class Just[A](x:A) extends Maybe[A]

你可能不应该创建自己的Nothing,这会让人感到困惑,如果你指的是你的那个,或者类型层次结构底部的那个,你会让自己和编译器感到困惑。

答案 1 :(得分:1)

正如斯蒂芬所提到的,正确的方法是不要有特质而不是抽象类,但是,我认为解释为什么当前的方法失败以及如何修复它可能是有益的。

主要问题在于这一行:

cv2.bitwise_and(src1, src2[, dst][, mask]) → dst

首先(如上所述)你不应该打电话给你的对象。其次,将对象设置为扩展Maybe [Nothing]。没有什么不具备任何实际值,因此您无法将其用作对象。此外,您不能将对象本身用作构造函数参数,因为这会导致循环行为。

您需要的是底部类型(即所有A共有的类型)和该类型的对象。没有什么是底部类型,但没有对象。

一种可能的解决方案是将自己限制为AnyRef(即可以为空的对象)并使用具有有效对象的Null底部类型(null):

 case object Nothing extends Maybe[Nothing](Nothing)

答案 2 :(得分:0)

对于阿萨夫·门德尔森的回答,这是一个澄清,但这对评论来说太大了。

case object Nothing extends Maybe[Nothing](Nothing)

Scala具有用于类型和值的单独命名空间。 Nothing中的case object Nothing是一个值。 Nothing中的Maybe[Nothing]是一种类型。由于您没有定义名为Nothing的类型,因此它引用自动导入的scala.Nothing,您必须将此类型的值作为参数传递。根据定义,它没有值,但是例如由于case object Nothing extends Maybe[Nothing](throw new Exception)表达式的类型为throwNothing会进行编译。而是传递值Nothing,即您定义的case object;其类型写为Nothing.type

答案 3 :(得分:0)

  

如何传递Nothing而不是Nothing.type?

似乎没有办法这样做。 正如它在http://www.scala-lang.org/api/2.9.1/scala/Nothing.html所说:

  

没有此类型的实例。