Question

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?

Was it helpful?

Solution 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"
+        ]

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top