我试图用Haskell将简单(但非常大)的树结构保存到二进制文件中。结构看起来是这样的:如何将树数据结构保存到Haskell中的二进制文件
-- For simplicity assume each Node has only 4 childs data Tree = Node [Tree] | Leaf [Int]这里是我所需要的数据看磁盘上:
- 每个节点有4个32位偏移到它的孩子,然后按照孩子的开始。
- 我不太在乎叶子,假设它只有n个连续的32位数字。
- 对于实践目的,我需要一些节点标签或其他附加数据 但现在我不关心那么多。
对我来说Haskellers编写二进制文件时的首选是Data.Binary.Put库。但是,由于我在第一号子弹中遇到了问题。特别是,当我要将节点写入文件时,要写下子偏移量,我需要知道当前的偏移量和每个子项的大小。
这不是Data.Binary.Put提供的东西,所以我认为这必须是Monad变形金刚的完美应用。但即使听起来很酷且功能强大,但迄今为止,我还没有采用这种方法取得成功。
我问了另外两个问题,我认为这会帮助我解决问题here和here。我必须说,每次我收到非常好的答案,都会帮助我进一步取得进展,但不幸的是,我仍然无法解决整个问题。
Here是我到目前为止,它仍然泄漏太多的内存是实用的。
我很想拥有使用这种功能的方法的解决方案,但也会感激任何其他解决方案。
这棵树有多大,你想象的文件大小是多少?这个答案决定了你是否可以使用任何类型的put类型结构,或者如果你需要一些涉及单遍遍历但修改已经写好的结构部分的东西...... – sclv 2011-03-01 18:36:43
二进制序列化通常需要知道尺寸要写入的数据(例如列表以长度为前缀)。你可以住文本序列化(可能是更大的文件)?如果不能通过写入中间文件并将它们拼接在一起(可怕但可能)来做一些技巧。 同样在你的测试代码中,输入是合成的 - 如果你的真实数据不是合成的,你可能会在内存中使用它,所以普通的二进制序列化不会强制任何不在堆中的东西。 – 2011-03-01 18:40:30
@sclv,上面提到的“我到目前为止所拥有的东西”的链接指向我一直在研究一段时间的更大程序的摘录。在原始程序中,我读取了一个具有相似结构的二进制文件,对其进行转换(主要是为了节点上没有太多的子节点),然后将其保存回去。源文件的大小介于50MB到200MB之间,所以我认为目标文件的大小相似。 – 2011-03-01 22:23:48