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
但是您可以看到,这将返回一个新的解析器-我想不出将第一个解析器作为参数提供的方法。
看起来解析器实际上是StateT monad转换器中的生产者。我想知道是否存在一种从StateT提取生产者的方法,以便evalStateT可以应用于foldAll解析器,而生产者可以从解码解析器应用。
但是,这可能完全是错误的方法。
简而言之,我的问题是:
使用Pipes.Aeson解析文件时,折叠文件中所有对象的最佳方法是什么?
decode
您可以使用的解析镜头来代替使用。它将的生产者转变为解析的JSON值的生产者。decoded
Pipes.Aeson.Unchecked
ByteString
{-# 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 ()
并将生产者插入fold的折叠中Pipes.Prelude
,例如sum
:
main :: IO ()
main = do
total <- P.sum intProducer'
putStrLn $ show total
在ghci中:
λ :main
10
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句