Commit Graph

73 Commits

Author SHA1 Message Date
Fintan Halpenny
8bd410f8f5
Use Strict Text for Parsing. (#422)
* Benchmark Prelude files

* Add issue 108 example

* Some cleaning up

* Remove printing of files

* Add bounds

* Clean cabal formatting

* Using strict Text instead of lazy Text

* Fixing compilation errors

* Update tests

* Cleanup

* Revert benchmark merge

* Update comments to replace the mention of Builder to Text
2018-06-01 11:54:07 -06:00
Greg Pfeil
429aeaffb8 Normalize each import before it is cached. (#392)
In tests on Dhall configs we use at work, I saw speedups between 33–90% on
extremely complicated configs with this change.

It mostly just adds a line calling `normalize`, but also threads the Normalizer
through a bunch of places to make sure we normalize properly for the context.
2018-05-17 08:07:46 -07:00
Gabriel Gonzalez
2e631db47a
Switch grammar of Natural and Integer (#381)
... as standardized in https://github.com/dhall-lang/dhall-lang/pull/141

Now `Natural`s no longer require a leading `+` and non-negative `Integer`s
require a leading `+`

This also adds a `doctest` test suite to prevent regressions in haddock
examples
2018-05-12 09:20:08 -07:00
Javier Neira
8c0f09fb4d Support for ghc-7.10.3 / lts-6.27 (#340) 2018-04-06 14:39:21 -07:00
Oliver Charles
14b083ba76 Add RecordType, record and field (#338) 2018-04-05 07:08:17 -07:00
Gabriel Gonzalez
d473f83ef5
Fix derived Inject instance for sum types (#348)
Related to #346

This fixes the `GenericInject` instance for a sum type with two
constructors to include the type of the alternative constructor.  For
example, before this change you would get the following incorrect
conversion:

```
$ cabal repl lib:dhall
>>> :set -XDeriveGeneric
>>> :set -XDeriveAnyClass
>>> data Amount = Debit Scientific | Credit Scientific deriving (Show, Generic, Inject, Interpret)
>>> Dhall.Core.pretty (embed inject (Debit 5.45))
"< Debit = { _1 = 5.45 } >"
```

... which is missing the `Credit` alternative.

After this change you get the correct result:

```
< Debit = { _1 = 5.45 } | Credit : { _1 : Double } >
```
2018-04-01 17:48:18 -07:00
Oliver Charles
922e20e6ab Replace trifecta with megaparsec (#268)
The long-term motivation for this change is so that we can eventually use a
separate `attoparsec`-based lexing step to greatly increase parsing speed since
the `trifecta`/`parsers` API doesn't allow tokens other than `Char`.

The secondary motivation for this is that `megaparsec` is a smaller dependency
that is more actively maintained.
2018-03-27 09:09:20 -07:00
Joe Kachmar
c87e5d9980 Switches from text-format to formatting (#330) 2018-03-18 22:05:30 -07:00
Gabriel Gonzalez
6b56aa5a0f
Fix semantics of {List,Optional,Natural}/build (#300)
This fixes all of the build built-ins  to match the standard semantics

The easiest way to illustrate the problem is the following example from
the test suite:

```haskell
  λ(id : ∀(a : Type) → a → a)
→ Natural/build
  (   λ(natural : Type)
    → λ(succ : natural → natural)
    → λ(zero : natural)
    → id natural (succ zero)
  )
```

According to the standard semantics that should normalize to:

```haskell
λ(id : ∀(a : Type) → a → a) → id Natural +1
```

... but before this change it was not reducing at all.  After this
change it reduces correctly.

However, there is a further issue, which is that correctly implementing
the semantics leads to poor time complexity for `List/build` since it is
specified in terms of repeatedly prepending a single element, which
leads to quadratic time complexity since lists are implemented in terms
of `Vector` under the hood.

You might think that you could use the efficient approach for
expressions like this:

```haskell
List/build
Bool
( λ(list : Type)
→ λ(cons : Bool → list → list)
→ λ(nil : list)
→ cons True (cons False nil)
)
```

... and then fall back on the slower approach for more interesting cases
such as this:

```haskell
  λ(id : ∀(a : Type) → a → a)
→ List/build
  Bool
  ( λ(list : Type)
  → λ(cons : Bool → list → list)
  → λ(nil : list)
  → id list (cons True (cons False nil))
  )
```

... but that does not work either!  The reason why is that very often
you don't use `List/build` directly and instead use it indirectly via
helper functions such as `Prelude/List/concat`:

```haskell
let concat : ∀(a : Type) → List (List a) → List a
    =   λ(a : Type)
    →   λ(xss : List (List a))
    →   List/build
        a
        (   λ(list : Type)
        →   λ(cons : a → list → list)
        →   λ(nil : list)
        →   List/fold
            (List a)
            xss
            list
            (   λ(xs : List a)
            →   λ(ys : list)
            →   List/fold
                a
                xs
                list
                cons
                ys
            )
            nil
        )

in  concat
```

... so what happens is that if you try to normalize something like:

```haskell
concat Text [["Example"]]
```

... the `concat` function will be normalized first, which will cause the
`List/build` to be normalized when its argument is still abstract, which will
trigger the slow path for the semantics.

Consequently, this change also modifies Dhall lists to be backed by
`Data.Sequence.Seq` instead of `Data.Vector.Vector`, so that
`List/build` can always use the correct implementation of semantics
in linear time while still implementing other operations on lists
reasonably efficiently.

This in turn triggers another change to the `OptionalLit` constructor
to use `Maybe` to store the payload instead of `Vector`.  The only
reason that `OptionalLit` originally used `Vector` was so that
`List/head` and `List/last` could be implemented as just a slice into
the `ListLit` vector, but now that it's not a vector any longer it's
simpler to just use a more accurate `Maybe` type to represent the
payload.
2018-02-26 10:50:27 -08:00
Gabriel Gonzalez
4a02a219d2
Expand haddock coverage (#277) 2018-02-18 08:44:12 -08:00
Gabriel Gonzalez
0091b09183
Add support for Scientific (#256)
Fixes https://github.com/dhall-lang/dhall-lang/issues/86

This change has two benefits:

* Users of the Haskell API can now marshal Dhall values of type `Double` into
  Haskell values of type `Scientific`
* The `dhall` executable no longer loses precision when dealing with
  values that have a large exponent (see the newly added test)
2018-02-08 07:24:12 -08:00
Oliver Charles
0e7d620fa8 Add Interpret String (#247) 2018-02-01 21:20:18 -08:00
Gabriel Gonzalez
067ff6d939
dhall-format now preserves the order of fields (#246)
Related to #244

This updates Dhall's syntax tree to use an insert-ordered hashmap to store
record fields and union alternatives.  This in turn implies that they will be
formatted in the same order that they were originally parsed.

This is a breaking change to the API due to changing the type of map used in the
syntax tree.
2018-02-01 21:16:24 -08:00
Oliver Charles
430fc08f45 Add unit, string, pair and list types (#227) 2018-01-22 16:38:42 -08:00
Gabriel Gonzalez
4e94f631ea
Preserve string interpolation when using dhall-format (#220)
Fixes #216

This changes the internal representation of `TextLit` to be able to
store an interpolated string literal.  Preserving string interpolation in
the syntax tree means that `dhall-format` can also preserve
interpolation.

This also simplifies a lot of the string-interpolation-related code,
which is now simpler and more strongly typed.
2018-01-21 16:32:28 -08:00
Oliver Charles
2ae05f9dad Add 'inputWith' (#222)
'inputWith' is like 'input', but allows for a custom typing context and
normalizer.

Fixes #213.
2018-01-21 16:31:29 -08:00
Gabriel Gonzalez
593434ffbd
Add genericAuto (#195)
Fixes #156
2017-12-28 10:17:45 -08:00
Armando Ramirez
28db97ca91 Simpe custom typechecking for Embedded terms (#186) 2017-12-05 11:01:44 -08:00
bosu
0e8a4c9b25 Add Inject instance for () (#147) 2017-09-29 12:49:34 -07:00
bosu
9e0ab9a755 Inject instances for Data.Set, Data.Sequence (#113) 2017-08-28 08:58:46 -07:00
bosu
a03de76a41 Add Inject instances for Word types (#112) 2017-08-27 16:06:57 -07:00
bosu
5b1cbb08af Implement Inject instance for unnamed tuples. (#107)
This removes the need for `R2`
2017-08-26 08:02:52 -07:00
bosu
b58100759d Interpret instance for unnamed data fields (#103)
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 }
```
2017-08-22 13:30:28 -07:00
Gabriel Gonzalez
63a8bf0976 Small tweaks to documentation of R2 (#101)
This slightly modifies the documentation of `R2` to further clarify its
relationship to 2-tuples
2017-08-21 19:10:08 -07:00
Gabriel Gonzalez
27264a0ba4 Add Interpret/Inject instances for [] 2017-08-21 11:36:59 -07:00
bosu
fa51d5e40e Add Inject, Interpret instances for tuples. (#100)
Uses R2 intermediate type to represent tuples in Dhall.
2017-08-21 09:08:51 -07:00
bosu
2a186dcabb Add Inject instance for Int (#99) 2017-08-20 10:24:24 -07:00
bosu
333fc1d000 Export InputType (#91) 2017-07-27 11:44:37 -07:00
Gabriel Gonzalez
8b3ebbc832 Remove use of Template Haskell. Fixes #89
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
2017-07-25 19:51:40 -07:00
Gabriel Gonzalez
fae3232480 Add support for marshaling simple Dhall functions to Haskell functions (#88) 2017-07-22 04:53:24 -07:00
bosu
0221dd4432 Exports Type internals. (#86)
Adds trivial comments on extend, extract functions.

Fixes https://github.com/Gabriel439/Haskell-Dhall-Library/issues/26.
2017-07-11 14:04:44 -07:00
Ville Tirronen
4707a8ff62 Raw input (#85)
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).
2017-07-05 09:05:47 -07:00
Chris Martin
7a0c03df57 add Type and Interpret instance for strict Text (#82) 2017-07-01 22:24:39 -07:00
Gabriel Gonzalez
e7e799f4da Fix InterpretOptions to work inside Optional/List. Fixes #33
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
2017-03-27 07:00:17 -07:00
Gabriel Gonzalez
6630470651 Fix InterpretOptions to affect nested records. Fixes #33
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.
2017-03-26 09:20:04 -07:00
Gabriel Gonzalez
505a786c6d Add support for customizing derived auto implementation. Fixes #22 (#24)
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
2017-02-23 09:35:52 -08:00
Gabriel Gonzalez
df892060aa Export InvalidType 2017-02-05 10:32:32 -08:00
Gabriel Gonzalez
782d118c97 Provide a better error message if extract fails 2017-02-05 10:31:03 -08:00
Gabriel Gonzalez
cc5d22f4a8 Fix documentation
We *can* auto-generate `Interpret` instances for sum types
2017-02-05 07:27:07 -08:00
Gabriel Gonzalez
6509a16070 Remove unnecessary list type annotations in documentation 2017-02-05 07:23:25 -08:00
Gabriel Gonzalez
17290171fe Make Dhall -Wall-clean 2017-01-29 14:10:28 -08:00
Gabriel Gonzalez
961278d71a Change derived Interpret for data types with 1 constructor
They no longer need to be wrapped inside a union with 1 alternative and are
decoded directly from a record
2016-12-05 07:33:09 -08:00
Gabriel Gonzalez
20831bc24d Remove unnecessary first argument to load 2016-12-04 15:29:07 -08:00
Gabriel Gonzalez
94d7e99408 Update documentation 2016-12-04 15:19:01 -08:00
Gabriel Gonzalez
6e927f62f1 Tidy up pretty-printing logic 2016-12-04 15:10:27 -08:00
Gabriel Gonzalez
88776fd570 Update documentation 2016-11-24 22:13:36 -08:00
Gabriel Gonzalez
e34ce03ea4 Update documentation 2016-11-24 19:15:29 -08:00
Gabriel Gonzalez
96fe0ededb Update documentation 2016-11-24 14:59:02 -08:00
Gabriel Gonzalez
44fe3f7d6b Update documentation 2016-11-20 21:19:35 -08:00
Gabriel Gonzalez
38c0cd4866 Add detailed 2016-11-20 16:25:55 -08:00