2

の Eq (および show) のインスタンスを自動的に導出する方法はあります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)

編集: これは一種のハックであることは知っていますが、ほとんどすべて prelude 関数で行われるため、完全に悪意のあるコードがない限り、正しい結果が得られるはずです (これは、「オープンワールドの仮定」の場合に最もよくあるケースです)。 .

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 は現在、ほとんどの複雑な型 (つまり、拡張をオンにしてのみ記述できる型) のインスタンスの派生をサポートしていないと思います。ただし、このインスタンスを手動で記述するには、ここで提案した方法よりも少しクリーンな方法があります。Main.show新しいandを作成するのではなく、and(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 に答える