我正在尝试在Haskell中模拟以下简单的Scala ADT:
sealed trait Value
sealed trait Literal < Value
case object Null extends Literal
case class IntLiteral(value: Int) extends Literal
case class Variable(name: String) < Value
我模拟Literal
特征:
Prelude> data Literal = Null | IntLiteral Int deriving (Show, Eq)
目前为止,一切都好:
Prelude> Null
Null
Prelude> Null == IntLiteral 3
False
Prelude> IntLiteral 3 == IntLiteral 3
True
现在我试着介绍Variable
:
data Value = Literal | Variable String deriving (Show, Eq)
为什么这不起作用?
Prelude> Null == Variable "foo"
<interactive>:3:9: error:
• Couldn't match expected type ‘Literal’ with actual type ‘Value’
• In the second argument of ‘(==)’, namely ‘Variable "foo"’
In the expression: Null == Variable "foo"
In an equation for ‘it’: it = Null == Variable "foo"
Null
的类型是Literal
,Variable "foo"
是类型Value
。也可以有一个数据构造函数Literal
,与同名的类型无关。这些只是不同的东西,生活在哈斯克尔的不同命名空间中。如果你写
data Value = Literal Literal | ...
然后,第一个Literal
是数据构造函数的名称(在这种情况下创建类型为Value
的值(,第二个是类型的名称。