Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Pipes.Aeson在Haskell中对JSON进行流式解析_Json_Parsing_Haskell_Aeson_Haskell Pipes - Fatal编程技术网

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

使用Pipes.Aeson在Haskell中对JSON进行流式解析,json,parsing,haskell,aeson,haskell-pipes,Json,Parsing,Haskell,Aeson,Haskell Pipes,Pipes.Aeson库公开了以下功能: decode :: (Monad m, ToJSON a) => Parser ByteString m (Either DecodingError a) 如果将evalStateT与此解析器和文件句柄一起用作参数,则会从文件中读取一个JSON对象并进行解析 问题是文件包含多个对象(所有对象都是同一类型的),我希望在读取时折叠或缩小它们 Parse提供: foldAll :: Monad m => (x -> a -> x) -

Pipes.Aeson库公开了以下功能:

decode :: (Monad m, ToJSON a) => Parser ByteString m (Either DecodingError a)
如果将evalStateT与此解析器和文件句柄一起用作参数,则会从文件中读取一个JSON对象并进行解析

问题是文件包含多个对象(所有对象都是同一类型的),我希望在读取时折叠或缩小它们

Parse提供:

foldAll :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Parser a m b
但正如您所看到的,这将返回一个新的解析器——我想不出一种方法来提供第一个解析器作为参数

看起来解析器实际上是StateT monad转换器中的生产者。我想知道是否有一种方法可以从StateT中提取生产者,以便evalStateT可以应用于foldAll解析器,而生产者可以应用于decode解析器

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

简而言之,我的问题是:

使用Pipes.Aeson解析文件时,折叠文件中所有对象的最佳方法是什么?

您可以使用from
Pipes.Aeson.Unchecked
而不是使用
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 ()
并将制作人插入一个from
管道。前奏曲,如:


还请注意,函数和允许您应用于包中定义的折叠。

您还可以执行
缩放解码(foldAll step begin done)
@GabrielGonzalez啊,是的,我忘了还可以使用
缩放
将镜头应用于
解析器
s.@GabrielGonzalez,似乎使用
zoom decoded…
可以更容易地处理解析错误。
main :: IO ()
main = do
    total <- P.sum intProducer'
    putStrLn $ show total
λ :main
10