Haskell的代数数据类型:"伪扩展"

Ra *_*ead 5 haskell algebraic-data-types

我正在学习haskell中的代数DT.我想要做的是创建一种新的ADT,它可以"扩展"现有的ADT.我找不到如何表达我想要的东西,有人可以采用替代模式或者提出解决方案.我希望它们是不同的类型,但复制和粘贴只是一种愚蠢的解决方案.下面的代码最能描述我正在寻找的内容.

data Power =
  Abkhazia |
  -- A whole bunch of World powers and semi-powers
  Transnistria
    deriving (Eq, Show)

data Country = 
  --Everything in Power | 
  Netural |
  Water
    deriving (Eq, Show)
Run Code Online (Sandbox Code Playgroud)

编辑:我认为需要一点澄清......我希望能够做到这一点(在ghci)

let a = Abkhazia :: Country
Run Code Online (Sandbox Code Playgroud)

并不是

let a = Power Abkhazia :: Country
Run Code Online (Sandbox Code Playgroud)

Don*_*art 8

您需要将它们表示为树:

  data Power
      = Abkhazia
      | Transnistria
    deriving (Eq, Show)

  data Country 
      = Powers Power -- holds values of type `Power`
      | Netural      -- extended with other values.
      | Water
    deriving (Eq, Show)
Run Code Online (Sandbox Code Playgroud)

编辑:您对问题的扩展使这更简单:Country和Power类型共享一些常见行为作为"国家/地区".这表明您使用Haskell 的开放,可扩展类型类功能来为数据类型提供常见行为.例如

  data Power = Abkhazia | Transistria 

  data Countries = Neutral | Water
Run Code Online (Sandbox Code Playgroud)

然后,Power和Countries共享的类型类:

  class Countrylike a where
      landarea :: a -> Int -- and other things country-like entities share

  instance Countrylike Power where
      landarea Abkhazia    = 10
      landarea Transistria = 20

  instance Countrylike Countries where
      landarea Neutral     = 50
      landarea Water       = 0
Run Code Online (Sandbox Code Playgroud)

那么你可以landarea干净地使用权力或国家.您可以通过添加更多实例将其扩展到新类型.