2012-09-09 114 views
6

我已經開始了這個新的問題,因爲它成爲我上一個問題的後續。在Haskell中使用數據類型

如果我有一個由類似構造的兩種數據類型:

data A = X | Y | Z 
data B = X | Y 

有沒有辦法,我能以某種方式代表此爲:

data A = C | Z 
data B = C 

data C = X | Y 

,如果你能看到我在做什麼 - 我正在嘗試將X |分組Y轉換爲一種數據類型,然後可以被多種其他數據類型使用。我似乎無法讓編譯器允許這個,或者如果它,我不能模式匹配對X或Y,只有C?

我得到錯誤消息,C已被多次聲明。

我以爲我可以使用類型,但他們不允許多種類型。

編輯

即使我聲明很長的路要走(如下圖所示),它仍然不會編譯,說X和Y有多個聲明:

data A = X | Y | Z 
data B = X | Y 
+0

什麼你問的是A的'亞型'。它不會用關鍵字'data'聲明,它會創建一個新的類型,與之前的現有類型不相交。我不認爲Haskell具有任何這樣的功能,但是我沒有任何Haskell擴展。 – Gilles

+0

@Gilles:不,Haskell沒有任何亞型多態性。它只有參數多態性,並且通過類型類來實現ad-hoc多態。你可以得到的最接近的東西是存在型,但這幾乎是,但不完全是完全不同的東西。 –

+0

我會把這個作爲答案,但是因爲它不是很完美。你可以通過聲明一個類型類來接近你想要的東西,然後你需要這些「常見的東西」所需的操作。這是一種非常常見的方式來解決(解決此問題的一個版本)的問題。 –

回答

13

不僅不能這樣做這也是你不能完成你的第一個選擇 - 也就是說你不能在同一個模塊中有兩個類型,它們的構造函數都是XY

如果你能做到這一點,X的類型應該是 - C,AB?最顯而易見的答案是C,但是如果需要AB(注意Haskell沒有子類型),那麼您將無法使用它,這樣就會破壞整個構造的目的。

你能做的最好的是包裝下,在A和B的構造,即:

data A = AC C | Z 
data B = BC C 
data C = X | Y 

然後,你可以換一個C與任ACBC構造函數來創建類型的值分別爲AB

+0

剛編輯說我的第一個選項不起作用。當你說「換行」時,你的字面意思是「在C前包含一些其他的語法片段,以區別於原始的C」? – Lethi

+2

@丹恩。在我的例子中,你會寫'AC X'來創建一個類型值'A'和'BC X'來創建類型'B'的值。 'X'本身不能有兩種不同的類型。 – sepp2k

4

的原因,你不能做到這一點

data A = X | Y | Z 
data B = X | Y 

如下。說你編寫一些代碼以後:

foo n = (n,X) 

它建立一對在第二時隙中的第一時隙和X包括n。編譯器應該推斷什麼類型?一個有效的類型將是

foo :: a -> A -> (a,A) 

因爲XA類型的構造,但同樣有效的是

foo :: a -> B -> (a,B) 

因爲XB類型的構造函數。如果您有兩個具有相同名稱的構造函數,則不能推斷使用它們的函數的唯一類型。所以你不允許給同一個模塊中的兩個構造函數使用相同的名字。

1

你不能做到這一點:

data A = C | Z 
data B = C 

data C = X | Y 

(順便說一句,如果B相同C,那麼爲什麼有B呢?)

但你可以做的是這樣的:

data A = A_Other C | Z 
data B = B_Other C 

data C = X | Y 

然後你可以模式匹配這樣的:

foo :: A -> String 
foo (A_Other X) = "X" 
foo (A_Other Y) = "Y" 
foo (  Z) = "Z" 

bar :: B -> String 
bar (B_Other X) = "X" 
bar (B_Other Y) = "Y" 

foobar :: C -> String 
foobar X = "X" 
foobar Y = "Y" 

如果是有道理的......

0

你想要什麼你不能這樣做,因爲您聲明多個數據構造。在

data A = X | Y | Z 

你實際上引入具有3層構造(值)XY,和Z類型A。這就是爲什麼你的第一段代碼不能編譯,它看到了兩個不同類型的構造函數列出的相同名稱!如果你能做到這一點,你不得不問自己

X :: A 

X :: B 

以非面向對象的背景是可怕的!因此,您需要提供不同的構造函數名稱以共享該基礎數據,即C

如果你想這個因素,你可以做其他職位建議和獨特的構造每種數據類型分解出的數據

data A = CForA C | Z 
data B = CForB C 

data C = X | Y