【问题标题】:Haskell's algebraic data types: "pseudo-extend"Haskell 的代数数据类型:“伪扩展”
【发布时间】:2012-06-17 18:04:21
【问题描述】:

我正在学习 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)

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

let a = Abkhazia :: Country

而不是

let a = Power Abkhazia :: Country

【问题讨论】:

  • 想要这样做的原因通常来自 OO-y 学派 ;-),但您总是可以在 Country 中为持有 Power 的 PowerCountry 添加一个构造函数。
  • 嗯,请问阿布哈兹和德涅斯特河沿岸是如何进入一段 Haskell 代码的?你和这两个地方有什么关系?你在做某种游戏吗?您来自哪个国家/地区?
  • 阿布哈兹和德涅斯特河沿岸是en.wikipedia.org/wiki/List_of_sovereign_states“其他州”列表中的第一个也是最后一个我正在学习 Haskell,并想出了一些可以练习的东西。我想这可能是一场游戏,但我还没有打算。

标签: haskell algebraic-data-types


【解决方案1】:

您需要将它们表示为一棵树:

  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)

编辑:您对问题的扩展使这更简单:国家和权力类型都具有一些作为“国家”的共同行为。这建议您使用 Haskell 的开放、可扩展的 type class 特性来为数据类型提供常见行为。例如

  data Power = Abkhazia | Transistria 

  data Countries = Neutral | Water

那么,Power 和 Country 共享事物的类型类:

  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

那么您可以在大国或国家/地区干净利落地使用landarea。并且您可以在未来通过添加更多实例将其扩展到新类型。

【讨论】:

  • 这几乎是我想要的,但请看澄清。谢谢!
  • @Raisdead 你不能在 Haskell 中做到这一点,Don 会知道,...(但是,你可以使用多参数类型类来模拟子类型,这可能是你的意思。无论如何,唐的答案可能是你能得到的最好的,你应该使用什么。)
【解决方案2】:
{-# LANGUAGE GADTs, StandaloneDeriving #-}
data POWER
data COUNTRY

data CountryLike a where
    Abkhazia :: CountryLike a 
    Transnistria :: CountryLike a
    Netural :: CountryLike COUNTRY
    Water :: CountryLike COUNTRY

deriving instance Show (CountryLike a)
deriving instance Eq (CountryLike a)

type Power      = CountryLike POWER
type Country    = CountryLike COUNTRY

foo :: Power
foo = Abkhazia

bar :: Country
bar = Abkhazia

baz :: Country
baz = Netural

编辑:另一种选择是 type Power = forall a. CountryLike a(优点:使 Power 成为 Country 的子类型。缺点:这会使例如 Power -> Int 成为更高级别的类型,这往往很烦人(类型推断等.))

【讨论】:

    猜你喜欢
    • 2011-10-16
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    相关资源
    最近更新 更多