data A=A
data B=B
data AB=A|B
這點讓和AB型的A和B.哈斯克爾和類型的多個聲明錯誤
但最後一行導致編譯錯誤「B多次聲明」
我也試過喜歡做某事這個:
data A=Int|Bool
它編譯。但爲什麼ghc不允許我爲用戶定義的類型創建總和類型?
data A=A
data B=B
data AB=A|B
這點讓和AB型的A和B.哈斯克爾和類型的多個聲明錯誤
但最後一行導致編譯錯誤「B多次聲明」
我也試過喜歡做某事這個:
data A=Int|Bool
它編譯。但爲什麼ghc不允許我爲用戶定義的類型創建總和類型?
你要上當。你認爲當你寫data A=Int|Bool
時,你所說的A
類型的值可以是類型爲Int
的值或類型爲Bool
的值;但你實際上是說的是有兩個新的價值層次構造函數,分別是Int
和Bool
,每個構造函數都根本沒有信息,類型爲A
。同樣,你認爲data AB=A|B
說,你既可以A
類型或類型B
,但事實上,你的意思是你可以有值A
或值B
。
要記住的關鍵是有兩個命名空間,類型級別和術語級別,並且它們是不同的。
下面是如何做是正確的一個簡單的例子:
data A=A
data B=B
data AB=L A|R B
的最後一行聲明瞭兩個新名詞級構造,L
和R
。 L
構造函數的值爲類型A
,而R
構造函數的值爲類型B
。
你可能還喜歡Either
類型,定義如下:
data Either a b = Left a | Right b
您可以使用它來實現您的AB
,如果你想:
type AB = Either A B
同樣,你可以使用Either Int Bool
您標記爲Int
和Bool
的聯合。
既然'A'和'B'都沒有附加信息,可能會把它們扔掉完全使用'數據AB = A | B',但是如果沒有額外的代碼就很難看出來。 – Zeta
@Zeta我假設'數據A = A'和'數據B = B'只是更有趣的數據類型的佔位符。 –
因爲使用數據構造函數A
或B
創建的值的類型將不明確。例如,當我有a = B
時,a
的類型是什麼?它是A
或AB
?
您應該考慮使用不同的數據構造如下:
data A = MkA
data B = MkB
data AB = A A | B B
我想你的意思是數據AB = A A | B B'。畢竟,它應該是A和B的總和類型。 – Zeta
啊,對了,感謝糾正,意思是寫 –
當你說data AB = A | B
,你是不是指類型A
和B
,而是定義數據構造A
和B
。這些與前面幾行定義的構造函數衝突。
如果你想創建一個類型AB
那就是A
和B
的總和,你必須提供的數據構造函數包裹類型A
和B
,例如:
data AB = ABA A | ABB B
總和類型必須加標籤。 a+a
必須有兩個注射從a
。
要了解數據類型是如何工作的代數,舉一個簡單的例子:
data X = A | B C
這定義了一個新類型構造,X
,數據構造A
和B
一起。所述B
構造函數採用/保持類型C.的參數
在Haskell的主要規範總和類型是Either
:
data Either a b = Left a | Right b
哇!這個編輯*完全*改變了問題的細節,使所有的答案看起來有點愚蠢。這不是真正的推薦方式;相反,如果你發現你在第一個問題後仍然感到困惑,請打開一個新的問題,提供關於你的新問題的細節,它與前一問題有何不同,以及爲什麼你仍然感到困惑。 –
對不起,前一個實際上是一個簡化的...經過一些實驗後,我發現最好是發佈原來的一個,對不起......感謝您的詳細打字!你想更新你的答案嗎? – doofin
@doofin:不,你應該恢復你的編輯並打開一個新的問題 – Michael