Haskell嵌套代数数据类型

时间:2017-07-08 10:19:06

标签: haskell algebraic-data-types

我试图在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"

1 个答案:

答案 0 :(得分:1)

Null的类型为LiteralVariable "foo"的类型为Value。还可以有一个数据构造函数Literal,与具有相同名称的类型无关。在Haskell中,这些只是不同的东西,生活在不同的命名空间中。如果你写

data Value = Literal Literal | ...

然后,第一个Literal是数据构造函数的名称(在这种情况下创建类型Value的值),第二个是类型的名称。