我正在尝试在Haskell中序列化数据类型,并想知道如何序列化GADT。我试过的方法看起来像(使用Control.DeepSeq):
data Gadt a where
Cons1 :: Int -> Gadt Int
Cons2 :: Bool -> Gadt Bool
instance NFData Cons1 where rnf = genericRnf
instance NFData Cons2 where rnf = genericRnf
deriveSafeCopy ......
但是,这不会编译:GHC告诉我Cons1和Cons2不是有效的构造函数。我可以很好地序列化标准数据类型。序列化GADT的最佳方法是什么?
我想序列化GADT的原因是因为这个数据类型是我用于项目的Redis数据库中的一个键。
答案 0 :(得分:4)
这不能回答有关generics
的问题,因为@luqui指出
确定您的定义有点奇怪(请注意a
中的Cons1 :: a ->
是forall a
且与a
中的Gadt a
无关 - 我看不到你在这里做了什么 - 对不起)
基本上你可以把你想要的任何值放在那里
- Cons1 "Hello" -- :: Gadt Int
- Cons2 'c' -- :: Gadt Bool
- Cons2 [1,2,3] -- :: Gadt Bool
所有人都会给你一个Gadt Int
或Gadt Bool
- 但是当你对它进行模式匹配时,没有办法对这个值有任何意义,因为它实际上可能是任何东西(包括不是NFData
本身的实例
但原则上你就像使用普通ADT一样声明实例 - 就是在这里为不同的情况提供定义rnf
。
所以我想说我将你的GADT变成了这个:
data Gadt a where
Cons1 :: Int -> Gadt Int
Cons2 :: Bool -> Gadt Bool
然后这个实例声明就可以了:
instance NFData (Gadt a) where
rnf (Cons1 a) = rnf a
rnf (Cons2 a) = rnf a