2018-10-16 06:08:44 +02:00
|
|
|
# `dhall 1.18.0`
|
2016-12-05 05:04:50 +01:00
|
|
|
|
2018-10-20 18:27:16 +02:00
|
|
|
Dhall is a programmable configuration language that is not Turing-complete
|
2016-12-05 05:04:50 +01:00
|
|
|
|
2018-10-20 18:27:16 +02:00
|
|
|
You can think of Dhall as: JSON + functions + types + imports
|
2016-12-05 05:04:50 +01:00
|
|
|
|
2018-10-20 18:27:16 +02:00
|
|
|
You will probably want to read the language-agnostic README here:
|
|
|
|
|
|
|
|
* [`dhall-lang` `README`](https://github.com/dhall-lang/dhall-lang/blob/master/README.md)
|
|
|
|
|
|
|
|
This repository (and this `README`) focuses on the Haskell implementation of
|
|
|
|
Dhall
|
|
|
|
|
|
|
|
## Motivation
|
|
|
|
|
|
|
|
*"Why not configure my program using JSON or YAML?"*
|
|
|
|
|
|
|
|
JSON or YAML are suitable for small configuration files, but larger
|
|
|
|
configuration files with complex schemas require programming language features
|
|
|
|
to reduce repetition. Otherwise, the repetitive configuration files become
|
|
|
|
error-prone and difficult to maintain/migrate.
|
|
|
|
|
|
|
|
This post explains in more detail the motivation behind programmable
|
|
|
|
configuration files:
|
|
|
|
|
|
|
|
* [Programmable configuration files](https://github.com/dhall-lang/dhall-lang/wiki/Programmable-configuration-files)
|
|
|
|
|
|
|
|
*"Why not configure my program using Haskell code?"*
|
|
|
|
|
|
|
|
You probably don't want to rebuild your program every time you make a
|
|
|
|
configuration change. Recompilation is slow and requires the GHC toolchain
|
|
|
|
to be installed anywhere you want to make configuration changes.
|
2016-12-05 05:04:50 +01:00
|
|
|
|
|
|
|
## Quick start
|
|
|
|
|
|
|
|
Given this Haskell program saved to `example.hs`:
|
|
|
|
|
|
|
|
```haskell
|
|
|
|
-- example.hs
|
|
|
|
|
|
|
|
{-# LANGUAGE DeriveGeneric #-}
|
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
|
|
|
|
import Dhall
|
|
|
|
|
|
|
|
data Example = Example { foo :: Integer, bar :: Vector Double }
|
|
|
|
deriving (Generic, Show)
|
|
|
|
|
|
|
|
instance Interpret Example
|
|
|
|
|
|
|
|
main :: IO ()
|
|
|
|
main = do
|
|
|
|
x <- input auto "./config"
|
|
|
|
print (x :: Example)
|
|
|
|
```
|
|
|
|
|
|
|
|
... which reads in this configuration file:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
$ cat ./config
|
2017-03-12 20:23:24 +01:00
|
|
|
{ foo = 1
|
|
|
|
, bar = ./bar
|
|
|
|
}
|
2016-12-05 05:04:50 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
... which in turn references this other file:
|
|
|
|
|
|
|
|
```
|
|
|
|
$ cat ./bar
|
2017-02-05 21:13:06 +01:00
|
|
|
[3.0, 4.0, 5.0]
|
2016-12-05 05:04:50 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
... you can interpret the Haskell program like this:
|
|
|
|
|
|
|
|
```bash
|
2018-10-20 18:27:16 +02:00
|
|
|
$ nix-shell nix/test-dhall.nix
|
|
|
|
[nix-shell]$ runghc example.hs
|
2016-12-05 05:04:50 +01:00
|
|
|
Example {foo = 1, bar = [3.0,4.0,5.0]}
|
|
|
|
```
|
|
|
|
|
|
|
|
You can also interpret Dhall programs directly using the installed command-line
|
|
|
|
compiler:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
$ dhall
|
|
|
|
List/head Double ./bar
|
|
|
|
<Ctrl-D>
|
|
|
|
Optional Double
|
|
|
|
|
2018-10-20 18:27:16 +02:00
|
|
|
Some 3.0
|
2016-12-05 05:04:50 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
... and you can reference remote expressions or functions by their URL, too:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
$ dhall
|
2018-06-22 00:56:12 +02:00
|
|
|
let null = https://raw.githubusercontent.com/dhall-lang/Prelude/35deff0d41f2bf86c42089c6ca16665537f54d75/List/null
|
2016-12-05 05:04:50 +01:00
|
|
|
in null Double ./bar
|
|
|
|
<Ctrl-D>
|
|
|
|
Bool
|
|
|
|
|
|
|
|
False
|
|
|
|
```
|
|
|
|
|
|
|
|
Now go read the
|
2017-02-07 13:28:00 +01:00
|
|
|
[Dhall tutorial](https://hackage.haskell.org/package/dhall/docs/Dhall-Tutorial.html)
|
2016-12-05 05:07:19 +01:00
|
|
|
to learn more
|
2016-12-05 05:04:50 +01:00
|
|
|
|
2018-10-20 18:27:16 +02:00
|
|
|
## Building this project
|
2016-12-05 05:04:50 +01:00
|
|
|
|
2018-10-20 18:27:16 +02:00
|
|
|
Nix + Cabal is the recommended workflow for project development since continuous
|
|
|
|
integration uses Nix to build and test the project. Other development tools and
|
|
|
|
workflows are also supported on a best-effort basis.
|
2016-12-05 05:04:50 +01:00
|
|
|
|
2018-10-20 18:27:16 +02:00
|
|
|
You can build the project using only Nix by running this command from the root
|
|
|
|
of the repository:
|
2016-12-05 05:04:50 +01:00
|
|
|
|
2018-10-20 18:27:16 +02:00
|
|
|
```bash
|
|
|
|
$ nix-build
|
|
|
|
```
|
2016-12-05 05:04:50 +01:00
|
|
|
|
2018-10-20 18:27:16 +02:00
|
|
|
More commonly, you will want to incrementally build the project using `cabal`.
|
|
|
|
You can either do so inside of a `nix-shell`:
|
2016-12-05 05:04:50 +01:00
|
|
|
|
2018-10-20 18:27:16 +02:00
|
|
|
```bash
|
|
|
|
$ nix-shell
|
|
|
|
[nix-shell]$ cabal configure
|
|
|
|
[nix-shell]$ cabal build
|
|
|
|
[nix-shell]$ cabal test
|
|
|
|
```
|
2016-12-05 05:04:50 +01:00
|
|
|
|
2018-10-20 18:27:16 +02:00
|
|
|
... or you can add `nix: True` to your `~/.cabal/config` file and then you can
|
|
|
|
run the same `cabal` commands without an explicit `nix-shell`:
|
2016-12-05 05:04:50 +01:00
|
|
|
|
2018-10-20 18:27:16 +02:00
|
|
|
```bash
|
|
|
|
$ cabal configure
|
|
|
|
$ cabal build
|
|
|
|
$ cabal test
|
|
|
|
```
|
2016-12-05 05:04:50 +01:00
|
|
|
|
|
|
|
## Development status
|
|
|
|
|
2017-10-27 11:01:33 +02:00
|
|
|
[![Build Status](https://travis-ci.org/dhall-lang/dhall-haskell.png)](https://travis-ci.org/dhall-lang/dhall-haskell)
|
2016-12-05 05:04:50 +01:00
|
|
|
|
|
|
|
The compiler is built upon a theoretically sound foundation, meaning that if
|
|
|
|
there are no bugs then the language will never crash and will always halt.
|
|
|
|
However, in practice the compiler needs to be battle-tested to weed out any
|
2018-10-20 18:27:16 +02:00
|
|
|
implementation bugs, so please open issues! 🙂
|
|
|
|
|
|
|
|
Read the following guide if you would like to contribute:
|
|
|
|
|
|
|
|
* [Contributing to Dhall](https://github.com/dhall-lang/dhall-lang/blob/master/.github/CONTRIBUTING.md)
|