これを行う完全に標準的なクラスはありませんが、自分で作成するのは非常に簡単です。これを行う 1 つの方法をスケッチします。
data P = A | B Q deriving Show
data Q = C | D R | E deriving Show
data R = F | G deriving Show
class Finite a where
allValues :: [a]
instance Finite P where
allValues = [A] ++ map B allValues
instance Finite Q where
allValues = [C] ++ map D allValues ++ [E]
instance Finite R where
allValues = [F] ++ [G]
私がこのようにインスタンスを書いたのは、それが非常に簡単で機械的であり、プログラム (例えば、ジェネリック プログラミングや Template Haskell) で実行できることを示すためです。タイプがerableBounded
である場合は、インスタンスを追加していくつかのレッグワークを実行することもできます。Enum
instance (Bounded a, Enum a) => Finite a where
allValues = [minBound..maxBound]
に追加deriving (Bounded, Show)
するとR
、書き込むインスタンスが 1 つ少なくなります。
とにかく、これで評価allValues :: [P]
して戻す[A,B C,B (D F),B (D G),B E]
ことができます。これを使用zip
し[0..]
て、エンコーディングなどを取得できます。
しかし、確かにこれは以前に行われました!私はシリアライゼーションをあまり (もしあったとしても) 使用していませんが、簡単に検索すると、binary パッケージとbinary-derive パッケージ が、インスタンスを自分で作成しなくても同様のことができることがわかります。それらが最初にあなたが望むことをするかどうかを確認します。