使用管道将值序列化为 JSON 数组
Serializing values to JSON array with pipes
我想将传入值序列化为 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 的答案以获得 Consumer
,但它不输出右括号:
jsonExporter :: Consumer (FilePath, AnalysisResult) IO ()
jsonExporter = do
lift $ putStr "["
P.map encode >-> insertCommas
lift $ putStr "]"
我不明白为什么。
这个管段:
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 "]"
我想将传入值序列化为 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 的答案以获得 Consumer
,但它不输出右括号:
jsonExporter :: Consumer (FilePath, AnalysisResult) IO ()
jsonExporter = do
lift $ putStr "["
P.map encode >-> insertCommas
lift $ putStr "]"
我不明白为什么。
这个管段:
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 "]"