在 Scala 中使用构造函数扩展 class 的案例对象
Case object extending class with constructor in Scala
我是 Scala 的初学者,正在尝试了解有关抽象数据类型的更多信息。我定义了以下定义来复制选项类型:
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?,但没有帮助。
也许更像这样。你的 Nothing 不应该有值,只有类型。此外,人们通常使用特征而不是抽象 类.
sealed trait Maybe[+A]
case object None extends Maybe[Nothing]
case class Just[A](x:A) extends Maybe[A]
您可能不应该创建自己的 Nothing,那会造成混淆,您会混淆自己和编译器,不知道您指的是您自己的 Nothing 还是类型层次结构底部的 Nothing。
正如 Stephen 所提到的,正确的做法是不要有 trait 而不是抽象 class,但是,我认为解释当前方法失败的原因以及如何修复它。
主要问题在于此行:
case object Nothing extends Maybe[Nothing](Nothing)
首先(如前所述)您不应该将您的对象命名为 Nothing。其次,您将对象设置为扩展 Maybe[Nothing]。 Nothing 不能有任何实际值,所以你不能将它用作对象。此外,您不能将对象本身用作构造函数参数,因为那样会导致循环行为。
您需要的是拥有一个底层类型(即所有 A 共有的类型)和该类型的对象。 Nothing 是底层类型但没有对象。
一个可能的解决方案是将自己限制在 AnyRef(即可为 null 的对象)并使用具有有效对象(null)的 Null 底部类型:
sealed abstract class Maybe[+A <: AnyRef](x:A)
case object None extends Maybe[Null](null)
这是对 Assaf Mendelson 的回答的一些澄清,但对于评论来说太大了。
case object Nothing extends Maybe[Nothing](Nothing)
Scala 对类型和值有单独的命名空间。 case object Nothing
中的Nothing
是一个值。 Nothing
in Maybe[Nothing]
是一种类型。由于您没有定义名为 Nothing
的类型,它指的是自动导入的 scala.Nothing
并且您必须将此类型的值作为参数传递。根据定义,它没有值,但例如case object Nothing extends Maybe[Nothing](throw new Exception)
会编译,因为 throw
表达式的类型是 Nothing
。相反,您传递值 Nothing
,即您正在定义的值 case object
;它的类型写成 Nothing.type
.
How do I pass Nothing instead of Nothing.type?
好像没有办法啊。
正如它在 http://www.scala-lang.org/api/2.9.1/scala/Nothing.html 中所说:
there exist no instances of this type.
我是 Scala 的初学者,正在尝试了解有关抽象数据类型的更多信息。我定义了以下定义来复制选项类型:
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?,但没有帮助。
也许更像这样。你的 Nothing 不应该有值,只有类型。此外,人们通常使用特征而不是抽象 类.
sealed trait Maybe[+A]
case object None extends Maybe[Nothing]
case class Just[A](x:A) extends Maybe[A]
您可能不应该创建自己的 Nothing,那会造成混淆,您会混淆自己和编译器,不知道您指的是您自己的 Nothing 还是类型层次结构底部的 Nothing。
正如 Stephen 所提到的,正确的做法是不要有 trait 而不是抽象 class,但是,我认为解释当前方法失败的原因以及如何修复它。
主要问题在于此行:
case object Nothing extends Maybe[Nothing](Nothing)
首先(如前所述)您不应该将您的对象命名为 Nothing。其次,您将对象设置为扩展 Maybe[Nothing]。 Nothing 不能有任何实际值,所以你不能将它用作对象。此外,您不能将对象本身用作构造函数参数,因为那样会导致循环行为。
您需要的是拥有一个底层类型(即所有 A 共有的类型)和该类型的对象。 Nothing 是底层类型但没有对象。
一个可能的解决方案是将自己限制在 AnyRef(即可为 null 的对象)并使用具有有效对象(null)的 Null 底部类型:
sealed abstract class Maybe[+A <: AnyRef](x:A)
case object None extends Maybe[Null](null)
这是对 Assaf Mendelson 的回答的一些澄清,但对于评论来说太大了。
case object Nothing extends Maybe[Nothing](Nothing)
Scala 对类型和值有单独的命名空间。 case object Nothing
中的Nothing
是一个值。 Nothing
in Maybe[Nothing]
是一种类型。由于您没有定义名为 Nothing
的类型,它指的是自动导入的 scala.Nothing
并且您必须将此类型的值作为参数传递。根据定义,它没有值,但例如case object Nothing extends Maybe[Nothing](throw new Exception)
会编译,因为 throw
表达式的类型是 Nothing
。相反,您传递值 Nothing
,即您正在定义的值 case object
;它的类型写成 Nothing.type
.
How do I pass Nothing instead of Nothing.type?
好像没有办法啊。 正如它在 http://www.scala-lang.org/api/2.9.1/scala/Nothing.html 中所说:
there exist no instances of this type.