小编imm*_*ate的帖子

使用Pipes.Aeson在Haskell中流式解析JSON

Pipes.Aeson库公开以下函数:

decode :: (Monad m, ToJSON a) => Parser ByteString m (Either DecodingError a)
Run Code Online (Sandbox Code Playgroud)

如果我将evalStateT与此解析器和文件句柄作为参数一起使用,则会从文件中读取单个JSON对象并进行解析.

问题是文件包含几个对象(所有类型都相同),我想在阅读时折叠或缩小它们.

Pipes.Parse提供:

foldAll :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Parser a m b
Run Code Online (Sandbox Code Playgroud)

但是你可以看到这会返回一个新的解析器 - 我想不出提供第一个解析器作为参数的方法.

看起来Parser实际上是StateT monad变换器中的Producer.我想知道是否有一种从StateT中提取Producer的方法,以便evalStateT可以应用于foldAll Parser,以及解码Parser中的Producer.

这可能完全是错误的方法.

我的问题,简而言之:
使用Pipes.Aeson解析文件时,折叠文件中所有对象的最佳方法是什么?

parsing json haskell aeson haskell-pipes

9
推荐指数
1
解决办法
853
查看次数

在Haskell中折叠生产者/分析器时的空间爆炸

假设我有一个这样的模块:

module Explosion where

import Pipes.Parse (foldAll, Parser, Producer)
import Pipes.ByteString (ByteString, fromLazy)
import Pipes.Aeson (DecodingError)
import Pipes.Aeson.Unchecked (decoded)
import Data.List (intercalate)
import Data.ByteString.Lazy.Char8 (pack)
import Lens.Family (view)
import Lens.Family.State.Strict (zoom)

produceString :: Producer ByteString IO ()
produceString = fromLazy $ pack $ intercalate " " $ map show [1..1000000]

produceInts :: 
    Producer Int IO (Either (DecodingError, Producer ByteString IO ()) ())
produceInts = view decoded produceString

produceInts' :: Producer Int IO ()
produceInts' = produceInts >> return ()

parseBiggest …
Run Code Online (Sandbox Code Playgroud)

memory reduce haskell stream haskell-pipes

6
推荐指数
1
解决办法
218
查看次数

标签 统计

haskell ×2

haskell-pipes ×2

aeson ×1

json ×1

memory ×1

parsing ×1

reduce ×1

stream ×1