使用 Haskell 对巨大的 json 数组进行子采样

Subsampling a huge json array with Haskell

我有一个巨大的 Json 文件,我想避免将其完全加载到内存中。它的结构非常简单:它由一个包含任意元素的大数组组成。我只是想通过随机删除大部分元素来转换数组,然后简单地输出转换后的 Json.

Haskell 似乎很适合这个懒惰的问题,我认为这会是一个很好的 Haskell 练习(我不是专家,我也不太了解FP理论)。

我找到了 pipes-aeson [1],这似乎是我想要的,但尝试了一段时间后,我不得不承认我被卡住了。几乎没有示例,虽然我可以使用 Pipes 对数据进行下采样,但使用 Parser 对象似乎更复杂。我发现的选项 (evalStateT) 是严格的并且会解析整个事情,而无需我干预。

也许 Lenses 可以解决我的问题,但它们非常抽象,我不明白它们是什么,也不知道如何使用它们。

有比我知识渊博的人提供一点指导吗?

[1] https://hackage.haskell.org/package/pipes-aeson-0.4.1.3/docs/Pipes-Aeson.html#t:DecodingError

我相信您将无法为此重用aeson。来自 aeson Parser documentation:

It can be useful to think of parsing as occurring in two phases:

  • Identification of the textual boundaries of a JSON value. This is always strict, so that an invalid JSON document can be rejected as soon as possible.
  • Conversion of a JSON value to a Haskell value. This may be either immediate (strict) or deferred (lazy); see below for details.

第一个项目符号似乎暗示(至少对我而言)解析器不会给你任何东西,直到它检查了足够的它应该解析的字符串以确定解析是成功还是失败 -- 在你的情况,这几乎可以肯定是整个字符串。所以这个阶段会将整个对象(的某种表示)立即放入内存中。

这 属性 目前大多数解析器组合器库都是如此。您可以考虑将 uu-parsinglib 作为替代方案;我相信它支持返回部分解析。有一篇非常易读的论文描述了从其 Hackage 页面链接到的功能。