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

在Scala中使用构造函数扩展类的Case对象,scala,functional-programming,abstract-data-type,Scala,Functional Programming,Abstract Data 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

我是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。键入

我参考了以下问题以寻求提示:
,但这没有什么帮助。

也许更像这样。你的Nothing不应该有值,只有类型。此外,人们通常使用特征而不是抽象类

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

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

可能更像这样。你的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,而不是抽象类,我认为,解释当前方法失败的原因以及如何修复它可能会提供信息

主要问题在于这一行:

 case object Nothing extends Maybe[Nothing](Nothing)
第一件事(如上所述)你不应该称你的对象为“无”。第二,将对象设置为“扩展”或“无”。任何东西都不能有任何实际值,因此不能将其用作对象。此外,不能将对象本身用作构造函数参数,因为这会导致循环行为

您需要的是有一个底部类型(即所有a都有一个共同的类型)和一个该类型的对象。没有任何东西是底部类型,但没有对象

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


sealed抽象类可能[+A正如Stephen所提到的,正确的方法是不要有trait,也不要抽象类,但是,我认为解释当前方法失败的原因以及如何修复它可能是有益的

主要问题在于这一行:

 case object Nothing extends Maybe[Nothing](Nothing)
第一件事(如上所述)您不应该将对象称为Nothing。第二,您将对象设置为extend-Maybe[Nothing]。Nothing不能有任何实际值,因此您不能将其用作对象。此外,您也不能将对象本身用作构造函数参数,因为这会导致循环行为

您需要的是有一个底部类型(即所有a都有一个相同的类型)和一个该类型的对象。没有任何东西是底部类型但没有对象

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


sealed abstract class可能[+A这对阿萨夫·门德尔森的回答有点澄清,但它太大了,无法发表评论

case object Nothing extends Maybe[Nothing](Nothing)

Scala对类型和值有单独的名称空间。
Nothing
中的
case object Nothing
是一个值。
中的
Nothing
可能是[Nothing]
是一种类型。由于您没有定义名为
Nothing
的类型,它引用了自动导入的
scala。Nothing
并且您必须将此类型的值作为参数传递。根据定义,它没有值,但例如
case对象Nothing扩展可能[Nothing](引发新异常)
将进行编译,因为抛出表达式的类型是
Nothing
。相反,您传递的值是
Nothing
,即与您定义的
case对象相同;它的类型写为
Nothing。type

这对Assaf Mendelson的回答来说有点澄清,但它太大了,无法发表评论

case object Nothing extends Maybe[Nothing](Nothing)
Scala对类型和值有单独的名称空间。
Nothing
中的
case object Nothing
是一个值。
中的
Nothing
可能是[Nothing]
是一种类型。由于您没有定义名为
Nothing
的类型,它引用了自动导入的
scala。Nothing
并且您必须将此类型的值作为参数传递。根据定义,它没有值,但例如
case对象Nothing扩展可能[Nothing](引发新异常)
将进行编译,因为
throw
表达式的类型是
Nothing
。相反,您传递的值是
Nothing
,即与您定义的
case对象相同;其类型写为
Nothing.type

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

似乎没有办法这样做。 正如上面所说:

不存在此类型的实例

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

似乎没有办法这样做。 正如上面所说:

不存在此类型的实例


创建一个不同的
None
也可能会引起一些混乱,但它肯定比定义第二个
Nothing
要好。实际上,您不能定义第二个
Nothing
。谢谢。但是当用参数化构造函数扩展类时,我们如何使用case对象呢?甚至有可能吗?创建一个不同的
None
也可能会引起一些混乱,但它肯定比定义第二个
要好。实际上,您不能定义第二个
。谢谢。但是,在使用参数化构造函数扩展类时,我们如何使用case对象?甚至可能吗?