2017-07-08 55 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類型的值,在這種情況下)的名字,第二個是一個類型的名字。