0

我想将传入的值序列化为 JSON。每个值都有一个toJSON实例。最终结果应该是一个列表。当前代码如下:

import Pipes
import qualified Pipes.Prelude as P

-- assume a source of elements
main :: IO ()
main = runEffect $ source >-> P.map encode >-> P.stdoutLn

问题是这样每一行都包含一个有效的 JSON 对象,但我希望整个结果是可解析的。我希望在第一个对象[输出一个字符之前,然后是每个元素后跟一个逗号,最后是另一个]. 我怎么能用管道做到这一点?

电流输出:

$ prog
{"key": "value"}
{"key": "value"}

期望的输出:

$ prog
[{"key": "value"},
{"key": "value"}]

我找到了pipes-aeson,但我不明白我应该如何使用它提供的功能。

编辑:我修改了 ErikR 的答案以获得 a Consumer,但它不输出右括号:

jsonExporter :: Consumer (FilePath, AnalysisResult) IO ()
jsonExporter = do
    lift $ putStr "["
    P.map encode >-> insertCommas
    lift $ putStr "]"

我不明白为什么。

4

1 回答 1

1

该管段:

for cat $ \x -> lift $ do { putStr ", "; putStrLn x }

将在管道中的每个元素之前发出一个逗号。

为了对第一个元素进行特殊处理,我们只需展开循环一次:

insertCommas = do
  x1 <- await
  lift $ putStrLn x1      -- print first element w/o a comma
  for cat $ \x -> lift $ do { putStr ", "; putStrLn x }

现在您可以将流式 JSON 管道编写为:

putStr "["
runEffect $ source >-> P.map encode >-> insertCommas
putStrLn "]"
于 2015-11-01T13:54:59.967 回答