Maps unnamed data fields to the positional record keys. For example:
```haskell
data Foo = Foo Bool Integer Natural deriving (Generic, Interpret)
```
... is mapped to this Dhall data type:
```haskell
Record { _1 : Bool, _2 : Integer, _3 : Natural }
```
This replaces all uses of `NeatInterpolation` with either multi-line
strings or `unlines`. This allows Dhall to be compiled without using
Template Haskell, which in turn enables cross-compilation
Added a function that allows doing `input` from a closed
Dhall `Expr` instead of text. This is hugely useful when
working with Dhall in AST level (for example, using custom
types / normalization). For example, suppose that you have
built a custom primitive that requires a record as an argument.
With `rawInput` you can just extract the record into a Haskell
data type and process it without need to work with maps and other
bits of AST.
For context of this commit, see #79 (and also #26).
Consider the following Haskell program:
```
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: Vector GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
Before this change the above program attempts to decode a value of type:
```
{ userName : Text, dotfilesRepo : List { _host : Text, _repo : Text } }
```
... when it should be decoding a value of type:
```
{ userName : Text, dotfilesRepo : List { host : Text, repo : Text } }
```
This change ensures that `InterpretOptions` correctly propagate to elements of
`List` or `Optional` values
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
This adds a new `deriveAuto` utility that you can customize with
`InterpretOptions` in order to transform the expected field or constructor
labels that Dhall expects
The most common use of this is to support data types that prefix field names
with underscores for lens support
The primary reason for this change is to make it easier to describe these values
both in documentation and in informal communication between developers.
Before, you'd have to say things like:
* A value of type `Maybe` (incorrect)
* A `Maybe` value (sounds weird)
* A value of type `Maybe a` for some `a` (correct, but very verbose)
Now you can say an `Optional` value and the meaning is precise and clear
A secondary reason for this change is to keep the terminology close to the
intended use of the language for configuration files. Describing fields as
`Optional` instead of `Maybe` makes a lot of sense for configurations.
The disadvantage is that some uses of `Optional` don't make sense. For example,
consider the type of `List/head`:
List/head : ∀(a : Type) → List a → Optional a
It seems weird to say that the result of `List/head` is `Optional`. However,
many languages (such as Java/Scala/F#/Swift) already use this name or `Option` and
they get along just fine.