2017-07-08 73 views
0

我想下面这个简单的斯卡拉ADT在Haskell型号:哈斯克尔嵌套代数数据类型

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" 
+0

* value *'Literal'是Value类型的构造函数;它不需要参数,并且与* type *'Literal'无关。你的意思是'数据值=文字文字| ...''空值==变量“foo”'? – melpomene

+0

如果我使用'数据值=文字文字|变量字符串派生(Show,Eq)'我得到预期的结果:'(Literal $ IntLiteral 3)==变量“foo”'=>'False'。我不确定我是否理解'Literal'构造函数和'Literal'类型之间的区别。 –

+0

'data .. ='后面的第一个单词以及每个后续的'|'后面是一个(值)构造函数名称。其他人指的是类型。语法类似于'data T .. = K1 T11 T12 ... | K2 T21 T22 ... | K3 T31 T32 ... | ...' – chi

回答

0
Null

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

data Value = Literal Literal | ... 

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