是否有办法懒散地"读"?

fho*_*fho 9 haskell

我可能只是花了一天的计算时间徒劳:)

问题是我(天真地)将大约3.5GB(压缩)的[(Text, HashMap Text Int)]数据写入文件,此时我的程序崩溃了.当然],数据末尾没有最终版本,而且它的庞大规模使得手动编辑变得不可能.

数据是通过格式化的Prelude.show,就在此时我意识到Prelude.read在返回任何数据之前需要将整个数据集存入内存(不可能).

现在......有没有办法恢复数据而无需手动编写解析器?

更新1

main = do
  s <- getContents
  let hs = read s :: [(String, M.Map String Integer)]
  print $ head hs
Run Code Online (Sandbox Code Playgroud)

我尝试过这个...但它只是在被操作系统杀死之前不断消耗更多内存.

Dan*_*ner 9

有点.你仍然会手动编写一个解析器...但它是一个非常简短且易于编写的解析器,因为几乎所有的解析器都会出货read.这个想法是这样的:read严格,但是reads,当处理单个元素时,是懒惰的.因此,我们只需要reads去除在处理单个元素时不期望的位.这是一个让你入门的例子:

> let s = "[3,4,5," ++ undefined
> reads (drop 1 s) :: [(Int, String)]
[(3,",4,5,*** Exception: Prelude.undefined
Run Code Online (Sandbox Code Playgroud)

undefined在最后包括了作为证据,它实际上是在String生成3在列表头部解析之前没有读完整个.


Ing*_*das 7

Daniels的答案可以扩展为使用此功能一次解析整个列表.然后,您可以按照您希望的方式直接访问它

lazyread :: Read a => [Char] -> [a]
lazyread xs = go (tail xs)
    where go xs = a : go (tail b)
        where (a,b) = head $ reads xs
Run Code Online (Sandbox Code Playgroud)