2013-10-22 45 views
0

轉換Type類,我想實現一個具有功能CONV,從給定的T形轉換的類。 僞代碼(不編譯)是這樣的:從給定類型

data T a b c d = List [a] | Tup1 a | Tup2 a b | Tup3 a b c deriving (Show) 

class ConvT t where 
    conv :: T a b c d -> t 

instance ConvT [a] where 
    conv (List x) = x 

instance ConvT (a,b) where 
    conv (Tup2 a b) = (a,b) 

我怎麼能這樣做? 請注意,我不打算在生產中使用它 - 我只是想更多地理解Haskell類型系統。

+0

您是否熟悉模式匹配?這聽起來就是你真正想要的。 –

回答

0

首先,請注意,這並沒有太大的意義,因爲你正試圖定義一個家庭的每一個都inhernetly部分功能。它可以做到,但只需要擴展。

溶液1:MPTC

class ConvT a b c d t where 
    conv :: T a b c d -> t 

instance ConvT a b c d [a] where 
    conv (List x) = x 

instance ConvT a b c d (a,b) where 
    conv (Tup2 a b) = (a,b) 

溶液2:約束種和類型的家庭。

class ConvT t where 
    type ConvC t a b c d :: Constraint 
    conv :: ConvC t a b c d => T a b c d -> t 

instance ConvT [a] where 
    type ConvC [a] a' b c d = a ~ a' 
    conv (List x) = x 

instance ConvT (a,b) where 
    type ConvC (a,b) a' b' c d = (a ~ a', b ~ b') 
    conv (Tup2 a b) = (a,b) 

注意:此代碼未經測試,但得到的想法。另外,不要這樣做。

+0

工作,謝謝。我不打算這樣做,但在我的情況下,具有這樣的conv函數會爲我節省大量的模式匹配。我需要在我調用的不同函數的開始處將一些數據包裝到T類型的ctor中。這很麻煩,使用conv函數會推斷正確的解包 - 如果類型不正確,則拋出錯誤。 –

0

您的類型類承諾您可以將(T a b c d)轉換爲t,對於任何類型a b c d t。但是實例聲明僅在類型之間存在某些對應關係時才起作用。例如,List情況下,只有工作,如果t[a],所以它不是你所定義的類型類的有效實例。

我不是一個Haskell專家,但我認爲這是不可能的,只是因爲沒有辦法寫一個正確的類型簽名conv