A configuration language guaranteed to terminate

Version on this page:1.32.0@rev:4
LTS Haskell 22.29:1.42.1
Stackage Nightly 2023-12-26:1.42.1
Latest on Hackage:1.42.1

See all snapshots dhall appears in

BSD-3-Clause licensed by Gabriel Gonzalez
Maintained by [email protected]
This version can be pinned in stack with:dhall-1.32.0@sha256:5d646b1b9ac979eb4dc5bd0bf0571bb5bcc7fda7123d12d63b6610451901b89e,34078

Dhall is an explicitly typed configuration language that is not Turing complete. Despite being Turing incomplete, Dhall is a real programming language with a type-checker and evaluator.

Use this library to parse, type-check, evaluate, and pretty-print the Dhall configuration language. This package also includes an executable which type-checks a Dhall file and reduces the file to a fully evaluated normal form.

Read Dhall.Tutorial to learn how to use this library





  • Supports version 15.0.0 of the standard
  • BREAKING CHANGE TO THE API: Auto-derive Generic/FromDhall/ToDhall with Template Haskell
    • Now the Dhall.TH.makeHaskell* utilities will include these derived instances in the generated declarations
    • This is a breaking change since users were likely already generating these instances separately, which will now conflict with the included instances
  • BREAKING CHANGE TO THE API: From/ToDhall no longer takes InterpretOptions argument
    • The types of the autoWith and injectWith methods have changed to take an InputNormalizer instead of an InterpretOptions
      • Note that InputNormalizer is a subset of InterpretOptions
    • This is a breaking change to how derived FromDhall / ToDhall instances are customized to more closely match how other Haskell packages customize derived instances (e.g. aeson with FromJSON / ToJSON)
      • Previously you would customize the behavior globally by passing in a top-level InterpretOptions record to autoWith
      • Now you can customize the behavior locally on a per-instance basis
    • This change enables the following change …
  • Add Dhall.Deriving module for deriving-via helpers
    • Now you can take advantage of the -XDerivingVia language extension to customize derived FromDhall/ToDhall instances, like this:
      • deriving (FromDhall, ToDhall) via Codec (SetSingletonConstructors Bare) Name
  • BREAKING CHANGE TO THE LANGUAGE: Match standard with respect to using toMap
    • https://example.com using toMap customHeaders is now a parse error and needs to be explicitly parenthesized as https://example.com using (toMap customHeaders)
    • The language standard had always required the parentheses, but the Haskell implementation was not correctly matching the standard
  • Fix formatting of indented comments containing empty lines
    • dhall format was previously not idempotent when formatting indented comments with empty lines
    • Specifically, the formatter kept indenting things further with each format, which this change fixes
  • Fix pretty-printer to preserve original numeric literals
    • Now dhall format will preserve numeric literals exactly how you wrote them
    • For example, 0xFF will no longer be reformatted as 255
  • Add dhall to-directory-tree support for Maps
    • Maps are now converted to directories (just like records)
  • Add manpage
    • … mainly for the benefit of people packaging Dhall for various distributions
  • Group commands in CLI
    • The command-line --help output now groups commands into useful sections
  • Fix numeric parsing for GHCJS
    • The GHCJS backend for Dhall was failing to parse numbers, which this change fixes
  • Fixes and improvements to error messages:
  • Fixes and improvements to the haddocks:









  • Supports version 8.0.0 of the standard
  • BREAKING CHANGE: Allow tabs and blank lines in multi-line strings
    • Blank lines are now ignored for the purpose of dedenting multiline strings
    • Lines with leading tabs (or mixed tabs and spaces) are now dedented, too, so long as they all share the same prefix
    • This is technically a breaking change, but unlikely to affect programs in practice, especially if they were formatted with dhall format. This change mainly affects programs that were not indented correctly.
    • See the changelog for standard version 8.0.0 for more details
  • BREAKING CHANGE: Simplify bare interpolations
    • Expressions like λ(x : Text) → "${x}" now simplify to λ(x : Text) → x
    • This is a technically breaking change because it changes how these sorts of expressions are serialized. This does not affect semantic integrity checks and the new simplified expressions are extensionally equivalent to their older counterpart expressions.
    • See the changelog for standard version 8.0.0 for more details
  • BREAKING CHANGE: Encode integrity check as multihash
    • Semantic integrity checks are now encoded using the multihash spec
    • This is a technically breaking change that does not perturb the hash for user-facing semantic integrity checks. This only affects how expressions with unresolved imports are serialized, but semantic integrity checks are only computed for fully-resolved imports.
    • See the changelog for standard version 8.0.0 for more details
  • BUG FIX: Fix type-checker to reject invalid record type annotations
  • BUG FIX: Custom header forwarding fixed
    • Forwarding custom headers could previously fail in various ways, such as:
      • Cyclic imports leading to endless network requests
      • Resolving a non-existent import for the custom headers
      • Resolving an existing but incorrect import for the custom headers
    • This change fixes that by forwarding custom headers by value instead of by reference
    • See: https://github.com/dhall-lang/dhall-haskell/pull/967
  • BUG FIX: Fix GHCJS support
  • BUG FIX: dhall diff no longer double-prints key-value separators
  • Feature: Record projection by expression
    • You can now project out a subset of record fields by the expected type
    • let t = { x : Natural } let p = { x = 1, y = 2 } in p.(t) = { x = 1 }
    • See the changelog for standard version 8.0.0 for more details
  • Feature: Inline headers
    • You no longer need to specify custom headers in a separate import. You can now specify them inline within the same file.
    • e.g.: https://example.com/x using [ { header = "Foo", value = "Bar" } ]
    • See the changelog for standard version 8.0.0 for more details
  • Feature: Allow Sort as a type annotation
    • An expression such as Kind → Kind : Sort will now type-check
    • Sort is still disallowed outside of a type annotation
    • See the changelog for standard version 8.0.0 for more details
  • Feature: Allow self-describe-cbor when decoding
    • Dhall expressions serialized as CBOR can be tagged to describe themselves as CBOR without affecting decoding
    • See the changelog for standard version 8.0.0 for more details
  • Feature: New --file option for dhall commands
  • Feature: New --cache flag for dhall freeze command
  • Feature: Add :clear command to dhall repl
  • Feature: New chunkExprs Traversal added to Dhall.Core
  • Feature: New Dhall.Optics module
  • More GHC 8.8 support





  • BUG FIX: Fix binary encoding to use correct standard version
    • This fixes computed hashes to correctly match standard version 5.0.0
    • This is not marked as a breaking change since it is a bug fix. The 1.20.0 release will be blacklisted on Hackage and users should upgrade from 1.19.* directly to 1.20.1
    • See: https://github.com/dhall-lang/dhall-haskell/pull/771







  • Fix test failure due to missing test data file






  • Increase upper bound on ansi-terminal and megaparsec









  • Add typeWithA for type-checking custom Embedded values
  • Fix dhall{,-*} executables to ignore ambient locale and use UTF8
  • Increase upper bound on tasty dependency


  • dhall executable can now format output using --pretty
  • Improved Unicode suppport on Windows


  • BREAKING CHANGE TO LANGUAGE: Add support for import integrity checks
    • In practice, the likelihood of this breaking code in the wild is astronomically low
    • This would only break code of the form sha256:aaa...aaa (i.e. a variabled named sha256 with a type annotation for a type with a name 64 characters long drawn from the first 6 characters of the alphabet)
  • BUG FIX: Fix parsing of single quotes in single-quoted strings
  • BUG FIX: Fix superfluous parentheses introduced by dhall-format
  • New dhall-hash executable
    • This goes hand-in-hand with the added support for integrity checks since the executable lets you compute the current hash of an import


  • BREAKING CHANGE TO LANGUAGE: Update parser to match standardized grammar
    • Trailing commas and bars no longer supported for union and record literals
    • Paths no longer permit commas
    • URL grammar is now RFC-compliant
    • Environment variables can now be quoted to support full range of POSIX-compliant names
    • Text literals support full set of JSON escape sequences (such as \u2192)
  • BREAKING CHANGE TO LANGUAGE: Single quoted strings strip leading newlines
  • BUG FIX: Fixed type-checking infinite loops due to non-type-checked variables in context
  • BUG FIX: Fixed type-checking bug due to missing context when type-checking certain expressions
  • BUG FIX: Fixed type-checking bug due to off-by-one errors in name shadowing logic
  • New dhall-format executable to automatically format code
  • Performance optimizations to Natural/fold and List/fold
  • Improved parsing performance (over 3x faster)
  • Union literals can now specify the set value anywhere in the literal
    • i.e. < A : Integer | B = False | C : Text >
  • New Inject instance for ()
  • Several tutorial fixes and improvements


  • BREAKING CHANGE TO THE API: Drop support for GHC 7.*
  • BREAKING CHANGE TO THE API: Add support for customizing Dhall import
    • This is a breaking change because this changes the type of loadWith
  • BREAKING CHANGE TO THE API: Add field to UnboundVariable error containing
  • BUG FIX: Fix parsing single quotes in string literals the name of the unbound variable
  • Add List/concatMap to the Prelude
  • You can now derive Inject and Interpret for types with unlabeled fields
  • Add new instances for Interpret:
    • []
    • (,)
  • Add new instance for Inject
    • [], Data.Set.Set, Data.Sequence.Seq
    • (,)
    • Int, Word8, Word16, Word32, Word64
  • Add Eq instance for Src


  • Increase upper bound on vector and optparse-generic


  • BREAKING CHANGE: Add list concatenation operator: (#)
    • This is a breaking change because it adds a new constructor to the Expr type which breaks exhaustive pattern matches
  • BREAKING CHANGE: Add Interpret support for lazy Text
    • This is a breaking change because it renames text to strictText
  • Add Interpret instance for decoding (a limited subset of) Dhall functions
  • Dhall no longer requires Template Haskell to compile
    • This helps with cross-compilation
  • Add rawInput utility for decoding a Haskell value from the Expr type
  • Add loadWith/normalizeWith utilities for normalizing/importing modules with a custom context
  • Export Type constructor


  • Fix missing Prelude files in package archive uploaded to Hackage


  • Fix missing tests/Tutorial.hs module in package archive uploaded to Hackage


  • BREAKING CHANGE TO THE LANGUAGE AND API: You can now supply custom headers for URL imports with the new using keyword
    • This is a breaking change to the language because this adds a new reserved using keyword
    • This is a breaking change to the API because this adds a new field to the URL constructor to store optional custom headers
  • BUG FIX: : is no longer a disallowed path character
    • This was breaking URL imports with a port
  • BUG FIX: If you import a home-anchored path (i.e. ~/foo) and that imports a relative path (like ./bar), then the canonical path of the relative import should be home-anchored (i.e. ~/bar). However, there was a bug that made lose the home anchor (i.e. ./foo/bar), which this release fixes likely fail due to no longer being home-anchored (i.e. `./foob
  • Add support for string interpolation
  • merge no longer requires a type annotation if you are merging at least one alternative
  • Expanded Prelude
    • ./Prelude/Optional/all
    • ./Prelude/Optional/any
    • ./Prelude/Optional/filter
    • ./Prelude/Optional/length
    • ./Prelude/Optional/null
    • ./Prelude/Text/concatMap
    • ./Prelude/Text/concatMapSep
    • ./Prelude/Text/concatSep
  • Rearrange detailed error messages to put summary information at the bottom of the message


  • BREAKING CHANGE TO THE API: Add support for new primitives, specifically:
    • (//) - Right-biased and shallow record merge
    • Optional/build (now a built-in in order to support build/fold fusion)
    • Natural/show
    • Integer/show
    • Double/show
    • Natural/toInteger
    • These all add new constructors to the Expr type, which would break exhaustive pattern matches
  • BREAKING CHANGE TO THE LANGUAGE: Imported paths and URLs no longer support the characters: “()[]{}<>:”
    • This reduces the number of cases where you have to add a space after imports
    • Note that this does not exclude the : in the URL scheme (i.e. http://)
  • Increase connection timeout for imports
  • Variable names now allow the - character for all but the first character
  • You can now escape identifiers with backticks
    • This lets you name identifiers so that they don’t conflict with reserved key words
    • This is most useful when converting Dhall to other file formats (like JSON) where you might need to emit a field that conflicts with one of Dhall’s reserved keywords
  • New --version flag for the dhall executable


  • BREAKING CHANGE: Add support for customizing derived Interpret instances
    • This is a breaking change to the Dhall library API since this changes the signature of the Interpret class by replacing the auto method with a more general autoWith method. This autoWith now takes an InterpretOptions argument that lets you customize derived field and constuctor names
    • In practice user programs that use the common path will be unaffected by this change
    • This is not a breaking change to the Dhall language
  • BREAKING CHANGE: Type annotations now bind more tightly than lambda abstraction
    • This is a breaking change to the Dhall language. An expression like this:

      λ(x : A) → y : B

      … used to parenthesized implicitly as:

      (λ(x : A) → y) : T

      … but is now parenthesized implicitly as:

      λ(x : A) → (y : T)

      This is now consistent with Haskell’s precedence and also consistent with the precedence of List and Optional type annotations

    • This change affects programs with an expression like this:

      -- Assuming that `y : B`
      λ(x : A) → y : A → B

      The above program would type-check before this change but not type-check after this change. You would you need to fix the above program by either changing the type signature to annotate just the type of y like this:

      λ(x : A) → y : B

      … or by adding explicit parentheses like this:

      (λ(x : A) → y) : A → B
    • This is not a breaking change to the Dhall library API

  • BREAKING CHANGE: Add support for importing a path’s contents as raw Text by adding as Text after the import
    • This is a breaking change to the Dhall language

    • This is technically a breaking change, but is extremely unlikely to affect you program. This only changes the behavior of old programs that had an expression of the form:

      /some/imported/function as Text

      … where /some/imported/function is an imported function being applied to two arguments, the first of which is a bound variable named as and the second of which is the type Text

    • This is not a breaking change to the Dhall library API

  • BREAKING CHANGE: Add support for importing environment variables using env:VAR syntax
    • This is a breaking change to the Dhall library API since it adds a new Path constructor

    • This also technically a breaking change to the Dhall language but extremely unlikely to affect your program. This only changes the behavior of old programs that had an expression of the form:


      … where env was the name of a bound variable and :VAR was a type annotation without spaces around the type annotation operator

      After this change the program would be interpreted as an import of the contents for the environment variable named VAR

  • BREAKING CHANGE: Support importing paths relative to home directory using ~/some/path syntax
    • This is a breaking change to the Dhall library API since it adds a new field to the File constructor indicating whether or not the imported path is relative to the home directory
    • This is not a breaking change to the Dhall language and the new syntax does not override any old syntax
  • Permit trailing commas and bars in record/union syntax
  • Improve location information for parsing errors


  • BREAKING CHANGE: Non-empty lists no longer require a type annotation
    • This is a breaking change to the Haskell library, not the Dhall language
    • This change does not break existing Dhall programs
    • The Expr type was modified in a non-backwards-compatible way
  • Add new exprA parser
  • Add new InvalidType exception if input fails on an invalid Type
  • Improve documentation and tutorial


  • Add support for Nix-style “double single-quote” multi-line string literals
  • Add isNormalized
  • Improve documentation and tutorial
  • Build against wider range of http-client versions


  • Initial release


  • Accidental premature upload to Hackage. This release was blacklisted