2

次のコードに関するリファクタリング/ベスト プラクティスのアドバイスを探しています。相互に排他的な「バージョン」ごとに個別のモジュールを維持しながら、拡張機能を回避したいと思います。私の現在の解決策は、クラスを使用し、存在量化を使用して、それぞれに共通の型を作成することCountrySetsです。

これは、OOP を使用していれば簡単に達成できますが、「機能的」とはまだ考えられません。

御時間ありがとうございます。

州.hs

{-# LANGUAGE ExistentialQuantification, RankNTypes  #-}
module Province where

  class Country a where
    --some stuff that is not important

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

  data Unit = Unit {
    power  :: forall a. (Show a, Eq a, Country a) => a, 
    piece :: Piece

  data Piece = Tank | Plane

  data Province = Province {
    power  :: Power,
    provName :: String
  } deriving (Eq)

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

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

Version1.hs

import Province

  data CountrySet1 =
    Country11 |
      Country12 
    deriving (Eq, Show)
  instance Country CountrySet1 where

  provs = 
    one1:one2:[]

  one1 = Province (Power Country11) "Place11"
  one2 = Province (Power Country12) "Place12" 

Version2.hs

import Province

  data CountrySet2 =
    Country21 |
    Country22 
      deriving (Eq, Show)
  instance Country CountrySet2 where

  provs = 
    two1:two2:[]

  two1 = Province (Power Country11) "Place21"
  two2 = Province (Power Country12) "Place22" 
4

1 に答える 1

7

データ型にクラス制約を入れる必要はありません。a代わりに、次のように、型クラスのインスタンス自体に制約を設定できるように、変数のデータ型をパラメーター化できます。

-- Note that I added a type variable to "Power"
data Power a = Power a | Neutral | Water

instance (Show a) => Show (Power a) where ...

instance (Eq a) => Eq (Power a) where ...

...または、ほとんどの人が行って使用することを行うことができますderiving:

data Power a = Power a | Neutral | Water deriving (Eq, Show)

これにより、作成したものとまったく同じインスタンスが生成されます (ただし、作成したEqものよりもはるかに効率的です)。拡張子不要!

特定のタイプになりたい場合はa、そう言うだけです。

-- Version1.hs
myValue1 :: Power CountrySet1
myValue1 = ...


-- Version2.hs
myValue2 :: Power CountrySet2
myValue2 = ...

これらは完全に互換性があり、両方の実装が共存できます。

于 2012-08-06T23:07:25.677 に答える