2

有没有办法自动为 Eq (和显示)派生实例Power?我设法找到http://www.haskell.org/ghc/docs/7.4.2/html/users_guide/deriving.html但我找不到与下面代码相关的任何解释。

此外,如果对下面创建的效果有更好的实践,我愿意接受建议,因为我是 Haskell 和函数式编程的新手。

{-# LANGUAGE ExistentialQuantification #-}

class Country a

instance Country CountrySet1 
data CountrySet1 =
  Belgium | 
  Algeria
    deriving (Show)

data Power =
  forall a. Country a => Power a |
  Netural |
  Water
    deriving (Eq, Show)

编辑:我知道这是一种 hack,但由于它几乎都是用前奏函数完成的,它应该得到正确的结果,除非存在完全恶意代码(这是“开放世界假设”最常见的情况) .

class Country a where
  show :: a -> String

instance Country CountrySet1 where
  show a = Prelude.show a

data CountrySet1  = 
  England | 
  Turkey
    deriving (Show)

data Power = 
  forall a. Country a => Power a |
  Netural |
  Water

instance Show Power where
  show (Power b) = "Power" ++ Main.show b
  show (Netural) = "Netural"
  show (Water) = "Water"

instance Eq Power where
  (==) a b = Prelude.show a == Prelude.show b
4

1 回答 1

1

我相信 GHC 目前不支持为大多数复杂类型(即只能通过扩展编写的类型)派生实例。但是,与您在此处建议的方法相比,手动编写此实例有一种更简洁的方法。如果您告诉编译器这没关系,您可以分派到and ,而不是创建一个新的Main.showand 。这样做的方法是制作和超类:(Main.==)Prelude.show(Prelude.==)ShowEqCountry

class (Show a, Eq a) => Country a

但是,正如我们从 的历史中了解到的那样Num,您通常希望将负担转移到其他地方。因此,您的另一个选择是将这些约束放在您的存在中:

data Power = forall a. (Show a, Eq a, Country a) => Power a | ...

再退一步,您也很可能根本不应该在这里使用存在主义。它们通常是不必要的。但是,如果没有更多上下文,很难给出更有针对性的重构建议。

于 2012-08-06T19:53:00.087 回答