[英]Streaming parsing of JSON in Haskell with Pipes.Aeson
Pipes.Aeson庫公開以下函數:
decode :: (Monad m, ToJSON a) => Parser ByteString m (Either DecodingError a)
如果我將evalStateT與此解析器和文件句柄作為參數一起使用,則會從文件中讀取單個JSON對象並進行解析。
問題是文件包含幾個對象(所有類型都相同),我想在閱讀時折疊或縮小它們。
Pipes.Parse提供:
foldAll :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Parser a m b
但是你可以看到這會返回一個新的解析器 - 我想不出提供第一個解析器作為參數的方法。
看起來Parser實際上是StateT monad變換器中的Producer。 我想知道是否有一種從StateT中提取Producer的方法,以便evalStateT可以應用於foldAll Parser,以及解碼Parser中的Producer。
這可能完全是錯誤的方法。
我的問題,簡而言之:
使用Pipes.Aeson解析文件時,折疊文件中所有對象的最佳方法是什么?
您可以使用Pipes.Aeson.Unchecked
的decoded
解析鏡頭 ,而不是使用decode
。 它將ByteString
的生產者轉變為解析的JSON值的生成者。
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Pipes
import qualified Pipes.Prelude as P
import qualified Pipes.Aeson as A
import qualified Pipes.Aeson.Unchecked as AU
import qualified Data.ByteString as B
import Control.Lens (view)
byteProducer :: Monad m => Producer B.ByteString m ()
byteProducer = yield "1 2 3 4"
intProducer :: Monad m => Producer Int m (Either (A.DecodingError, Producer B.ByteString m ()) ())
intProducer = view AU.decoded byteProducer
intProducer
的返回值有點可怕,但它只表示intProducer
完成解析錯誤和錯誤后的未解析字節,或者原始生成器的返回值()
在我們的例子中是()
)。
我們可以忽略返回值:
intProducer' :: Monad m => Producer Int m ()
intProducer' = intProducer >> return ()
和插件生產者成倍從Pipes.Prelude
,像sum
:
main :: IO ()
main = do
total <- P.sum intProducer'
putStrLn $ show total
在ghci:
λ :main
10
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.