This is short post to announce a new dhall-json
library which lets you compile the Dhall configuration language to both JSON and YAML. This in turn means that you can now program JSON and YAML using a non-Turing-complete programming language.
Here's a quick example of the library in action:
$ dhall-to-json <<< "{ foo = 1, bar = [1, 2, 3] }"
{"foo":1,"bar":[1,2,3]}
$ dhall-to-yaml <<< "{ foo = 1, bar = [1, 2, 3] }"
foo: 1
bar:
- 1
- 2
- 3
$ cat example
let indexed
= https://ipfs.io/ipfs/QmcTbCdS21pCxXysTzEiucDuwwLWbLUWNSKwkJVfwpy2zK/Prelude/List/indexed
in let map
= https://ipfs.io/ipfs/QmcTbCdS21pCxXysTzEiucDuwwLWbLUWNSKwkJVfwpy2zK/Prelude/List/map
in let words
= [ "Lorem"
, "ipsum"
, "dolor"
, "sit"
, "amet"
, "consectetur"
, "adipiscing"
, "elit"
]
in let makeRow
= λ(r : { index : Natural, value : Text })
→ { index = r.index
, background = if Natural/even r.index then "Green" else "Red"
, contents = r.value
}
in map
{ index : Natural, value : Text }
{ index : Natural, background : Text, contents : Text }
makeRow
(indexed Text words)
$ dhall-to-json <<< "./example"
[{"contents":"Lorem","index":0,"background":"Green"},{"contents":"ipsum","index":1,"background":"Red"},{"contents":"dolor","index":2,"background":"Green"},{"contents":"sit","index":3,"background":"Red"},{"contents":"amet","index":4,"background":"Green"},{"contents":"consectetur","index":5,"background":"Red"},{"contents":"adipiscing","index":6,"background":"Green"},{"contents":"elit","index":7,"background":"Red"}]
$ dhall-to-yaml <<< "./example"
- contents: Lorem
index: 0
background: Green
- contents: ipsum
index: 1
background: Red
- contents: dolor
index: 2
background: Green
- contents: sit
index: 3
background: Red
- contents: amet
index: 4
background: Green
- contents: consectetur
index: 5
background: Red
- contents: adipiscing
index: 6
background: Green
- contents: elit
index: 7
background: Red
This library bundles both JSON and YAML functionality together because Haskell's yaml
library reuses the exact same data type that Haskell's aeson
library uses to represent JSON (i.e. the Value
type). This means that if you can compile a Dhall expression to a Value
then you can render that Value
as both JSON and YAML.
Unlike the Dhall bindings to Nix, you can't compile most Dhall features to JSON or YAML, since they aren't real programming languages. After all, the whole point of this binding is to make JSON and YAML programmable! So if you try to compile anything other than primitive types or records you will get a compile error:
$ dhall-to-json <<< "λ(x : Bool) → x"
Error: Cannot translate to JSON
Explanation: Only primitive values, records, ❰List❱s, and ❰Optional❱ values can
be translated from Dhall to JSON
The following Dhall expression could not be translated to JSON:
↳ λ(x : Bool) → x
Right now I'm slowly adding Dhall integrations with new languages and configuration file formats so that people can use Dhall as a universal configuration language. So far I've targeted integrations that can reuse the initial Haskell implementation of Dhall (i.e. Nix, JSON, and YAML bindings). However, my next integration will probably reimplement Dhall in another language so that Dhall can be used to natively configure a wider range of languages without having to invoke a command-line dhall
executable.
I'm most likely to build the second implementation of Dhall in Rust so that I can also reuse the same implementation to expose a C and C++ API. However, I've never done this sort of thing before, so if this is a dumb idea, let me know!
You can find the dhall-json
package on Github or Hackage and if you would like to contribute to Dhall in general you can open an issue here.
No comments:
Post a Comment