6

I use the yaml library to serialize a value of type Map String t (or some type t). The order in the resulting output is rather random, which is suboptimal, as the file should be human readable.

Is there a way to control the serialization order of a map? Or, probably closer to the core of the problem, an aeson Object? If not, what are suitable workarounds?

Joachim Breitner
  • 25,395
  • 6
  • 78
  • 139

2 Answers2

2

Since 0.8.13, the yaml package contains the Data.Yaml.Prettty module. This allows you to configure how to pretty-print yaml documents, including ordering fields using setConfCompare

In one of my own projects, I started using it with a change like this:

 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"
+        ]
Joachim Breitner
  • 25,395
  • 6
  • 78
  • 139
1

With yaml, or aeson on which it is based, it is currently not easily possible, says the yaml author, but he has started some experimental support for it in the form of the Data.Yaml.Builder module.

Joachim Breitner
  • 25,395
  • 6
  • 78
  • 139