没有完全标准的类可以做到这一点,但自己制作一个非常容易。我将勾勒出一种方法:
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)。Bounded
如果类型是可擦除的,您还可以添加一个实例来为您做一些工作Enum
:
instance (Bounded a, Enum a) => Finite a where
allValues = [minBound..maxBound]
如果您现在添加deriving (Bounded, Show)
到R
,那就少写一个实例!
无论如何,现在我们可以评估allValues :: [P]
并返回[A,B C,B (D F),B (D G),B E]
- 然后您可以zip
使用它[0..]
来获取您的编码等等。
但肯定以前有人做过!我没有过多地使用序列化(如果有的话),但是快速搜索表明二进制包和二进制派生包 可以为您做类似的事情,而无需自己编写实例。我会先看看那些做你想做的事。