将一个map按照特定顺序序列化成YAML

6
我使用yaml库对类型为Map String t(或某种类型t)的值进行序列化。结果输出中的顺序相当随机,这是次优的,因为文件应该是容易阅读的。
是否有一种方法来控制映射的序列化顺序?或者,可能更接近问题的核心,一个aeson Object?如果没有,有什么合适的解决方法吗?

sort.toList 怎么样? - tomferon
成对的列表与映射序列化方式不同。 - Joachim Breitner
object . map (\(k,v) -> yourTypeToText k .= v ) . sort . toList - tomferon
你验证过了吗?对象本身是无序(哈希)映射。 - Joachim Breitner
我的错,只是我测试的值刚好合适。 - tomferon
2个回答

2
自从 0.8.13 版本以来,yaml 包包含 Data.Yaml.Pretty 模块。这使您可以配置如何漂亮打印 yaml 文档,包括使用 setConfCompare 排序字段。
在我的一个项目中,我 开始使用它,并进行了以下更改:
 writeTipToiYaml :: FilePath -> TipToiYAML -> IO ()
-writeTipToiYaml out tty = encodeFile out tty
+writeTipToiYaml out tty =
+    SBC.writeFile out (encodePretty opts tty)
+  where
+    opts = setConfCompare (compare `on` fieldIndex) defConfig
+    fieldIndex s = fromMaybe (length fields) $ s `elemIndex` fields
+    fields = map T.pack
+        [ "product-id"
+        , "comment"
+        , "welcome"
+        , "media-path"
+        , "gme-lang"
+        , "init"
+        , "scripts"
+        , "language"
+        , "speak"
+        , "scriptcodes"
+        ]

这在顶层可以工作,但嵌套的数据结构没有按比较器排序它们的字段 :( - Guy Gastineau
哎呀,真的吗?那听起来像是个bug。 - Joachim Breitner
哦,我忘记了这个注释。不,它确实有效。我只是非常错误。谢谢你提醒我驳斥自己的评论。 - Guy Gastineau

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接