4

現在、私はこのようなものを持っています:

data MyData = SomeData | MoreData | EvenMore
data DataLists = DataLists [MyData] [MyData]

これにより、明らかに次のようなことができます。

myDataList :: DataLists
myDataList = DataLists [SomeData, MoreData] [EvenMore, SomeData]

しかし、代わりに次のようなことをしたいと思います。

-- Static Module File:

class MyClass b where
    evaluate :: b -> Int

data SomeData = SomeData
data MoreData = MoreData
data EvenMore = EvenMore

instance MyClass SomeData where
    evaluate _ = 2
instance MyClass MoreData where
    evaluate _ = 3
instance MyClass EvenMore where
    evaluate _ = 4

data DataList = DataList [MyClass] [MyClass] -- Obviously this is wrong

コードのその部分を静的なままにしておきたいです。後で、そのモジュールを使用していくつかのタイプを追加し、データリストに追加したいので。モジュール全体が2つの異なるプロジェクトで使用され、編集を続ける必要がないため、これを個別に作成する必要があります。

data MyVeryOwnData = MyVeryOwnData
--I should be able to make up as many datastructures as I want

instance MyClass MyVeryOwnData where
   evaluate _ = 99

myList :: DataList
myList = DataList [MyVeryOwnData, SomeData] [SomeData, EvenMore]

MyVeryOwnDataを次のようにモジュールファイルに入れるだけでよいことに気付きました。

data MyData = SomeData | MyVeryOwnData ...

instance MyClass MyData where
    evaluate SomeData = 2
    evaluate MoreData = 3
    ... etc.

しかし、前に言ったように、に任意の量のデータ型を追加したいので、それはしたくありません。

4

1 に答える 1

6

あなたが探しているのは異種リストと呼ばれ、haskellは主にExistentialsまたはGADTの2つの方法でそれらをサポートします。実存主義の問題を解決した実行可能なコード例を示します。

{-# LANGUAGE ExistentialQuantification #-}

class Eval b where
    evaluate :: b -> Int

data SomeData = SomeData
data MoreData = MoreData
data EvenMore = EvenMore

instance Eval SomeData where
    evaluate _ = 2
instance Eval MoreData where
    evaluate _ = 3
instance Eval EvenMore where
    evaluate _ = 4

data Evalable = forall a . Eval a => Evalable a

instance Eval Evalable where
    evaluate (Evalable a) = evaluate a

pack :: Eval a => a -> Evalable
pack = Evalable

data DataLists = DataLists [Evalable] [Evalable]

getFirst :: DataLists -> [Evalable]
getFirst (DataLists xs ys) = xs

main = do
  let dl = DataLists [pack SomeData, pack EvenMore] [pack MoreData]
  print . map evaluate . getFirst $ dl

instance Eval MyVeryOwnData外部モジュールを追加できることは明らかです。そうすれば、packそれらの値がになりEvalable、内部に配置できるようになりますDatalists

于 2012-08-08T07:35:50.613 に答える