首页 > 解决方案 > Haskell 中的序列化

问题描述

鸟瞰,我的问题是:Haskell 中是否有通用的数据序列化机制?as-is

介绍

问题的根源确实不在于 Haskell。有一次,我尝试序列化一个 python 字典,其中对象的散列函数非常重。我发现在python中,默认的字典序列化并没有保存字典的内部结构,只是转储了一个键值对列表。结果,反序列化过程非常耗时,没有办法与之抗衡。我确信在 Haskell 中有一种方法,因为在我看来,使用 BFS 或 DFS 将纯 Haskell 类型自动转换为字节流应该没有问题。令人惊讶的是,但事实并非如此。此处讨论了此问题(以下引文)

目前,在不修改 HashMap 库本身的情况下,无法使 HashMap 可序列化。正如@mergeconflict 的回答所描述的那样,使用独立派生无法使 Data.HashMap 成为 Generic 的实例(用于谷物),因为 Data.HashMap 不会导出其所有构造函数(这是 GHC 的要求)。因此,序列化 HashMap 的唯一解决方案似乎是使用 toList/fromList 接口。

当前问题

我对Data.Trie bytestring-trie package有同样的问题。为我的数据构建一个 trie 非常耗时,我需要一种机制来序列化和反序列化这个轮胎。但是,它看起来像以前的情况,我看不到如何制作Data.TrieGeneric 的实例(或者,我错了)?

所以问题是:

  1. 是否有某种通用机制将纯 Haskell 类型投影到字节字符串?如果不是,是基本限制还是缺乏实现?

  2. 如果不是,那么修改bytestring-trie 包以使其成为 Generic 实例并使用序列化的最轻松的方法是什么Data.Store

标签: haskellserializationtypestemplate-haskell

解决方案


  1. 有一种使用紧凑区域的方法,但有一个很大的限制:

我们的二进制表示包含指向区域中对象信息表的直接指针。这意味着接收进程的信息表必须以与原始进程完全相同的方式布置;实际上,这意味着使用静态链接,使用完全相同的二进制文件并关闭 ASLR。这个 API 不做任何安全检查,如果你弄错了,可能会出现段错误。不要在不受信任的输入上运行它。

这也让我们深入了解目前不可能的通用序列化。数据结构包含非常具体的指针,如果您使用不同的二进制文件,这些指针可能会有所不同。将原始字节读入另一个二进制文件将导致指针无效。

在这个 GitHub issue 中有一些关于削弱这个要求的讨论。

  1. 我认为正确的方法是在上游打开一个问题或拉取请求以导出内部模块中的数据构造函数。这就是发生的事情,HashMap现在可以在其内部模块中完全访问。

更新:似乎已经有一个类似的未解决问题


推荐阅读