为Data.Text序列化实例?

rcr*_*ick 7 serialization haskell

我需要将数据类型序列化为使用的磁盘Data.Text,这是一个例子:

{-# LANGUAGE DeriveGeneric #-}
import Data.Serialize (Serialize)
import Data.Text (Text)
import GHC.Generics

data Foo = Foo Text deriving (Read, Show, Eq, Ord, Generic)
instance Serialize Foo
-- instance Serialize Text
Run Code Online (Sandbox Code Playgroud)

如上所述,这会产生错误:

No instance for (Serialize Text)
  arising from a use of `Data.Serialize.$gdmput'
Possible fix: add an instance declaration for (Serialize Text)
In the expression: (Data.Serialize.$gdmput)
In an equation for `put': put = (Data.Serialize.$gdmput)
In the instance declaration for `Serialize Foo'
Run Code Online (Sandbox Code Playgroud)

如果我取消注释该instance Serialize Text行,那么这个更加神秘的错误就出现了:

No instance for (Data.Serialize.GSerialize (Rep Text))
  arising from a use of `Data.Serialize.$gdmput'
Possible fix:
  add an instance declaration for
  (Data.Serialize.GSerialize (Rep Text))
In the expression: (Data.Serialize.$gdmput)
In an equation for `put': put = (Data.Serialize.$gdmput)
In the instance declaration for `Serialize Text'
Run Code Online (Sandbox Code Playgroud)

我可以Serialize手动实现该实例,但这似乎是孤立实例将成为一个真正问题的情况,而且,我认为我不太了解Data.Text快速正确地序列化/反序列化它.

这个问题有标准解决方案吗?(我也没有坚持使用Grain的Serialize实例,但我一直有一些与使用二进制包有关的版本问题; binary-0.5.1.1似乎不能很好地支持泛型,我想避免写样板.)

rcr*_*ick 5

根据Joachim Britner的建议,这是我最终使用的实例:

instance Serialize Text where
  put txt = put $ encodeUtf8 txt
  get     = fmap decodeUtf8 get
Run Code Online (Sandbox Code Playgroud)

如前所述,您可能需要不同的编码/解码功能,但结构应该相同.


Joa*_*ner 4

我认为缺失的实例应该被视为一个特征:Data.Text谈论文本,应该与其表示形式保持不同。因此,解决该问题的规范方法是将 编码Data.TextData.ByteString您想要的编码(或者更好的是,某些规范或元数据希望它是),然后序列化Data.ByteString.

最常见的编码函数可以在Data.Text.Encoding中找到。