2014-12-29 83 views

回答

4

不,這是不可能在香草哈斯克爾。你會過得更好寫它作爲

data Type1 = A1 | B1 Bool 
data Type2 = A2 Type1 | C2 Char | D2 Double 

這不需要任何語言擴展或類型系統的技巧,它更清楚地看到你的類型的依賴與延伸,而不是限制。如果你想能夠在它們之間進行轉換,那麼你可以做

type2ToType1 :: Type2 -> Maybe Type1 
type2ToType1 (A2 x) = Just x 
type2ToType1 _ = Nothing 

type1ToType2 :: Type1 -> Type2 
type1ToType2 = A2 
1

也許你在問更多的理論問題?有很多方法可以通過奇特的擴展來處理這類事情。例如,可以使用GADT將C1D1的類型限制爲Char -> Type1()Double -> Type1(),但保留其他構造函數處於打開狀態。因此,一切都將是Type1()類型,但只有前兩種可以是例如類型的。 Type1 Bool。下面是一個變種,也使用-XDataKinds,只是爲了您的娛樂:

{-# LANGUAGE GADTs, DataKinds, KindSignatures #-} 
{-# OPTIONS_GHC -Wall #-} 

data Status = Special | Common -- This type we will 'promote' to a kind. 
           -- Its constructors will be used as 
           -- names of (memberless) types. 

data Type (s :: Status) where 
    A :: Type s 
    B :: Bool -> Type s 
    C :: Char -> Type Common 
    D :: Double -> Type Common 

type Type1 = Type Common -- This has the same constructors as your Type1 
          -- i.e. A, B, C and D 
type Type2 = Type Special -- This has as many constructors as your Type2 
          -- but doesn't need a new declaration and wrapper 
          -- They are just A and B 

mkGeneral :: Type2 -> Type s 
mkGeneral A = A 
mkGeneral (B b) = B b -- ghc -Wall sees no patterns are missing 

mkCommon :: Type2 -> Type1 
mkCommon = mkGeneral 

mkSpecial :: Type s -> Maybe Type2 
mkSpecial A = Just A 
mkSpecial (B b) = Just (B b) -- ghc -Wall sees the need for the next line 
mkSpecial _ = Nothing