序列化仅由构造函数组成的有限(非递归)代数数据类型的最有效方法是什么?
例如
p = A
| B q
q = C
| D r
| E
r = F
| G
可以手动枚举这个简单小的定义的所有有效组合:
A 0x00
B C 0x01
B D F 0x02
B D G 0x03
B E 0x04
没有完全标准的类可以做到这一点,但是自己制作一个很容易。我将草拟一种方法:
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
erable:
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..]
获取编码等等。
但肯定已经做过了!我没有多次使用序列化(如果有的话),但快速搜索显示了这一点 二进制包 和 binary-derive包 可以为你做类似的事情,而不必自己编写实例。我会看看那些先做你想做的事。