2015-09-12 68 views
-1
data A=A 
data B=B 
data AB=A|B 

這點讓和AB型的A和B.哈斯克爾和類型的多個聲明錯誤

但最後一行導致編譯錯誤「B多次聲明」

我也試過喜歡做某事這個:

data A=Int|Bool 

它編譯。但爲什麼ghc不允許我爲用戶定義的類型創建總和類型?

+7

哇!這個編輯*完全*改變了問題的細節,使所有的答案看起來有點愚蠢。這不是真正的推薦方式;相反,如果你發現你在第一個問題後仍然感到困惑,請打開一個新的問題,提供關於你的新問題的細節,它與前一問題有何不同,以及爲什麼你仍然感到困惑。 –

+0

對不起,前一個實際上是一個簡化的...經過一些實驗後,我發現最好是發佈原來的一個,對不起......感謝您的詳細打字!你想更新你的答案嗎? – doofin

+1

@doofin:不,你應該恢復你的編輯並打開一個新的問題 – Michael

回答

5

你要上當。你認爲當你寫data A=Int|Bool時,你所說的A類型的值可以是類型爲Int的值或類型爲Bool的值;但你實際上是說的是有兩個新的價值層次構造函數,分別是IntBool,每個構造函數都根本沒有信息,類型爲A。同樣,你認爲data AB=A|B說,你既可以A類型或類型B,但事實上,你的意思是你可以有AB

要記住的關鍵是有兩個命名空間,類型級別和術語級別,並且它們是不同的。

下面是如何做是正確的一個簡單的例子:

data A=A 
data B=B 
data AB=L A|R B 

的最後一行聲明瞭兩個新名詞級構造,LRL構造函數的值爲類型A,而R構造函數的值爲類型B

你可能還喜歡Either類型,定義如下:

data Either a b = Left a | Right b 

您可以使用它來實現您的AB,如果你想:

type AB = Either A B 

同樣,你可以使用Either Int Bool您標記爲IntBool的聯合。

+0

既然'A'和'B'都沒有附加信息,可能會把它們扔掉完全使用'數據AB = A | B',但是如果沒有額外的代碼就很難看出來。 – Zeta

+1

@Zeta我假設'數據A = A'和'數據B = B'只是更有趣的數據類型的佔位符。 –

1

因爲使用數據構造函數AB創建的值的類型將不明確。例如,當我有a = B時,a的類型是什麼?它是AAB

您應該考慮使用不同的數據構造如下:

data A = MkA 
data B = MkB 
data AB = A A | B B 
+0

我想你的意思是數據AB = A A | B B'。畢竟,它應該是A和B的總和類型。 – Zeta

+0

啊,對了,感謝糾正,意思是寫 –

1

當你說data AB = A | B,你是不是指類型AB,而是定義數據構造AB 。這些與前面幾行定義的構造函數衝突。

如果你想創建一個類型AB那就是AB的總和,你必須提供的數據構造函數包裹類型AB,例如:

data AB = ABA A | ABB B 
1

總和類型必須加標籤。 a+a必須有兩個注射a

要了解數據類型是如何工作的代數,舉一個簡單的例子:

data X = A | B C 

這定義了一個新類型構造,X,數據構造AB一起。所述B構造函數採用/保持類型C.的參數

在Haskell的主要規範總和類型是Either

data Either a b = Left a | Right b