packages feed

dhall 1.34.0 → 1.35.0

raw patch · 208 files changed

+1703/−983 lines, 208 filesdep +tasty-silverdep −semigroupsdep ~megaparsecdep ~pretty-simpledep ~profunctorsPVP ok

version bump matches the API change (PVP)

Dependencies added: tasty-silver

Dependencies removed: semigroups

Dependency ranges changed: megaparsec, pretty-simple, profunctors, serialise

API changes (from Hackage documentation)

- Dhall: instance (Dhall.FromDhall a, Data.Hashable.Class.Hashable a, GHC.Classes.Ord a, GHC.Show.Show a) => Dhall.FromDhall (Data.HashSet.Base.HashSet a)
- Dhall: instance (Dhall.ToDhall k, Dhall.ToDhall v) => Dhall.ToDhall (Data.HashMap.Base.HashMap k v)
- Dhall: instance (GHC.Classes.Eq k, Data.Hashable.Class.Hashable k, Dhall.FromDhall k, Dhall.FromDhall v) => Dhall.FromDhall (Data.HashMap.Base.HashMap k v)
- Dhall: instance Dhall.ToDhall a => Dhall.ToDhall (Data.HashSet.Base.HashSet a)
- Dhall.Core: [recordFieldSrc] :: RecordField s a -> Maybe s
- Dhall.Parser.Expression: getSourcePos :: MonadParsec e s m => m SourcePos
+ Dhall: class GenericFromDhallUnion t f
+ Dhall: data Result f
+ Dhall: evaluateSettings :: (HasEvaluateSettings s, Functor f) => LensLike' f s EvaluateSettings
+ Dhall: genericUnionAutoWithNormalizer :: GenericFromDhallUnion t f => Proxy t -> InputNormalizer -> InterpretOptions -> UnionDecoder (f a)
+ Dhall: instance (Dhall.FromDhall a, Data.Hashable.Class.Hashable a, GHC.Classes.Ord a, GHC.Show.Show a) => Dhall.FromDhall (Data.HashSet.Internal.HashSet a)
+ Dhall: instance (Dhall.ToDhall k, Dhall.ToDhall v) => Dhall.ToDhall (Data.HashMap.Internal.HashMap k v)
+ Dhall: instance (GHC.Classes.Eq k, Data.Hashable.Class.Hashable k, Dhall.FromDhall k, Dhall.FromDhall v) => Dhall.FromDhall (Data.HashMap.Internal.HashMap k v)
+ Dhall: instance Dhall.FromDhall GHC.Int.Int16
+ Dhall: instance Dhall.FromDhall GHC.Int.Int32
+ Dhall: instance Dhall.FromDhall GHC.Int.Int64
+ Dhall: instance Dhall.FromDhall GHC.Int.Int8
+ Dhall: instance Dhall.FromDhall GHC.Types.Int
+ Dhall: instance Dhall.FromDhall GHC.Types.Word
+ Dhall: instance Dhall.FromDhall GHC.Word.Word16
+ Dhall: instance Dhall.FromDhall GHC.Word.Word32
+ Dhall: instance Dhall.FromDhall GHC.Word.Word64
+ Dhall: instance Dhall.FromDhall GHC.Word.Word8
+ Dhall: instance Dhall.ToDhall a => Dhall.ToDhall (Data.HashSet.Internal.HashSet a)
+ Dhall: int :: Decoder Int
+ Dhall: int16 :: Decoder Int16
+ Dhall: int32 :: Decoder Int32
+ Dhall: int64 :: Decoder Int64
+ Dhall: int8 :: Decoder Int8
+ Dhall: newManager :: (Functor f, HasEvaluateSettings s) => LensLike' f s (IO Manager)
+ Dhall: word :: Decoder Word
+ Dhall: word16 :: Decoder Word16
+ Dhall: word32 :: Decoder Word32
+ Dhall: word64 :: Decoder Word64
+ Dhall: word8 :: Decoder Word8
+ Dhall.Core: FieldSelection :: Maybe s -> !Text -> Maybe s -> FieldSelection s
+ Dhall.Core: FunctionBinding :: Maybe s -> Text -> Maybe s -> Maybe s -> Expr s a -> FunctionBinding s a
+ Dhall.Core: [fieldSelectionLabel] :: FieldSelection s -> !Text
+ Dhall.Core: [fieldSelectionSrc0] :: FieldSelection s -> Maybe s
+ Dhall.Core: [fieldSelectionSrc1] :: FieldSelection s -> Maybe s
+ Dhall.Core: [functionBindingAnnotation] :: FunctionBinding s a -> Expr s a
+ Dhall.Core: [functionBindingSrc0] :: FunctionBinding s a -> Maybe s
+ Dhall.Core: [functionBindingSrc1] :: FunctionBinding s a -> Maybe s
+ Dhall.Core: [functionBindingSrc2] :: FunctionBinding s a -> Maybe s
+ Dhall.Core: [functionBindingVariable] :: FunctionBinding s a -> Text
+ Dhall.Core: [recordFieldSrc0] :: RecordField s a -> Maybe s
+ Dhall.Core: [recordFieldSrc1] :: RecordField s a -> Maybe s
+ Dhall.Core: [recordFieldSrc2] :: RecordField s a -> Maybe s
+ Dhall.Core: data FieldSelection s
+ Dhall.Core: data FunctionBinding s a
+ Dhall.Core: functionBindingExprs :: Applicative f => (Expr s a -> f (Expr s b)) -> FunctionBinding s a -> f (FunctionBinding s b)
+ Dhall.Core: makeFieldSelection :: Text -> FieldSelection s
+ Dhall.Core: makeFunctionBinding :: Text -> Expr s a -> FunctionBinding s a
+ Dhall.Crypto: toString :: SHA256Digest -> String
+ Dhall.Deriving: asSingletonConstructors :: ToSingletonConstructors a => SingletonConstructors
+ Dhall.Freeze: freezeExpressionWithManager :: IO Manager -> FilePath -> Scope -> Intent -> Expr s Import -> IO (Expr s Import)
+ Dhall.Freeze: freezeImportWithManager :: IO Manager -> FilePath -> Import -> IO Import
+ Dhall.Freeze: freezeRemoteImportWithManager :: IO Manager -> FilePath -> Import -> IO Import
+ Dhall.Freeze: freezeWithManager :: IO Manager -> OutputMode -> PossiblyTransitiveInput -> Scope -> Intent -> CharacterSet -> Censor -> IO ()
+ Dhall.Import: [_newManager] :: Status -> IO Manager
+ Dhall.Import: defaultNewManager :: IO Manager
+ Dhall.Import: emptyStatusWithManager :: IO Manager -> FilePath -> Status
+ Dhall.Import: loadRelativeToWithManager :: IO Manager -> FilePath -> SemanticCacheMode -> Expr Src Import -> IO (Expr Src Void)
+ Dhall.Import: loadWithManager :: IO Manager -> Expr Src Import -> IO (Expr Src Void)
+ Dhall.Import: type HTTPHeader = (CI ByteString, ByteString)
+ Dhall.Import: type Manager = Manager
+ Dhall.Main: Dot :: ResolveMode
+ Dhall.Main: ListImmediateDependencies :: ResolveMode
+ Dhall.Main: ListTransitiveDependencies :: ResolveMode
+ Dhall.Main: data ResolveMode
- Dhall.Core: Field :: Expr s a -> Text -> Expr s a
+ Dhall.Core: Field :: Expr s a -> FieldSelection s -> Expr s a
- Dhall.Core: Lam :: Text -> Expr s a -> Expr s a -> Expr s a
+ Dhall.Core: Lam :: FunctionBinding s a -> Expr s a -> Expr s a
- Dhall.Core: RecordField :: Maybe s -> Expr s a -> RecordField s a
+ Dhall.Core: RecordField :: Maybe s -> Expr s a -> Maybe s -> Maybe s -> RecordField s a
- Dhall.Import: Status :: NonEmpty Chained -> [Depends] -> Map Chained ImportSemantics -> Maybe Manager -> (URL -> StateT Status IO Text) -> Substitutions Src Void -> Maybe (ReifiedNormalizer Void) -> Context (Expr Src Void) -> SemanticCacheMode -> Status
+ Dhall.Import: Status :: NonEmpty Chained -> [Depends] -> Map Chained ImportSemantics -> IO Manager -> Maybe Manager -> (URL -> StateT Status IO Text) -> Substitutions Src Void -> Maybe (ReifiedNormalizer Void) -> Context (Expr Src Void) -> SemanticCacheMode -> Status
- Dhall.Main: Text :: Input -> Mode
+ Dhall.Main: Text :: Input -> Output -> Mode

Files

CHANGELOG.md view
@@ -1,3 +1,44 @@+1.35.0++* [Supports version 18.0.0 of the standard](https://github.com/dhall-lang/dhall-lang/releases/tag/v18.0.0)+    * [Implement more efficient `with` desugaring](https://github.com/dhall-lang/dhall-haskell/pull/1993)+        * Chained `with` expressions will now be much more efficient+* [BREAKING CHANGE TO THE API: Preserve whitespace for `Lam` constructor](https://github.com/dhall-lang/dhall-haskell/pull/1980)+    * This change extends the `Lam` constructor to preserve whitespace around+      the variable binding+    * The motivation for this change is to enable `dhall-docs` to support+      jumping to definitions+    * You can replace your existing `Lam` constructors with+      `Dhall.Core.makeFunctionBinding`+* [BREAKING CHANGE TO THE API: Preserve whitespace for `Field` constructors](https://github.com/dhall-lang/dhall-haskell/pull/1991)+    * This change extends the `Field` constructor to preserve whitespace around+      the selected field+    * The motivation for this change is to enable `dhall-docs` to support+      jumping to definitions+    * You can use `Dhall.Core.makeFieldSelection` and+      `Dhall.Core.fieldSelectionLabel` to convert between the detailed and the+      simple representation of the selected field.+* [Add `FromDhall` instances for `{Int,Word}{,8,16,32,64}`](https://github.com/dhall-lang/dhall-haskell/pull/2012)+* [Add `--output` option for `dhall text` subcommand](https://github.com/dhall-lang/dhall-haskell/pull/1974)+* [Add `Dhall.Crypto.toString`](https://github.com/dhall-lang/dhall-haskell/pull/1976)+* [Make the HTTP `Manager` configurable](https://github.com/dhall-lang/dhall-haskell/pull/2027)+    * Several import-related functions now provide an alternative variants that+      allows the user to supply a custom `Manager`+    * You can use this to tweak HTTP request timeouts or use a different TLS+      manager (e.g. one from `http-client-openssl`)+* Fixes and improvements to code formatting+    * [#2000](https://github.com/dhall-lang/dhall-haskell/pull/2000)+    * [#2021](https://github.com/dhall-lang/dhall-haskell/pull/2021)++      The formatter now preserves comments for record fields (both record types+      and record literals)+* Fixes and improvements to documentation+    * [#2011](https://github.com/dhall-lang/dhall-haskell/pull/2011)+    * [#2013](https://github.com/dhall-lang/dhall-haskell/pull/2013)+    * [#2014](https://github.com/dhall-lang/dhall-haskell/pull/2014)+* Fixes and improvements to test suite+    * [#2020](https://github.com/dhall-lang/dhall-haskell/pull/2020)+ 1.34.0  * [Supports version 17.1.0 of the standard](https://github.com/dhall-lang/dhall-lang/releases/tag/v17.1.0)
benchmark/deep-nested-large-record/Main.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} module Main (main) where +import Data.Void (Void) import Gauge (defaultMain)  import qualified Data.Sequence   as Seq@@ -21,16 +22,19 @@     }   } -issue412 :: Core.Expr s TypeCheck.X -> Gauge.Benchmarkable+issue412 :: Core.Expr s Void -> Gauge.Benchmarkable issue412 prelude = Gauge.whnf TypeCheck.typeOf expr   where     expr       = Core.Let (Core.Binding Nothing "prelude" Nothing Nothing Nothing prelude)       $ Core.ListLit Nothing       $ Seq.replicate 5-      $ Core.Var (Core.V "prelude" 0) `Core.Field` "types" `Core.Field` "Little" `Core.Field` "Foo"+      $ Core.Var (Core.V "prelude" 0) `Core.Field` types `Core.Field` little `Core.Field` foo+    types = Core.makeFieldSelection "types"+    little = Core.makeFieldSelection "little"+    foo = Core.makeFieldSelection "Foo" -unionPerformance :: Core.Expr s TypeCheck.X -> Gauge.Benchmarkable+unionPerformance :: Core.Expr s Void -> Gauge.Benchmarkable unionPerformance prelude = Gauge.whnf TypeCheck.typeOf expr   where     expr =@@ -48,12 +52,14 @@                         Nothing                         Nothing                         Nothing-                        (prelude `Core.Field` "types" `Core.Field` "Big")+                        (prelude `Core.Field` types `Core.Field` big)                     )                     (Core.Prefer Core.PreferFromSource "big" "big")                 )             )             "x"+    types = Core.makeFieldSelection "types"+    big = Core.makeFieldSelection "Big"  main :: IO () main =
benchmark/parser/Main.hs view
@@ -6,11 +6,10 @@ import Control.Monad     (forM) import Data.Map          (Map, foldrWithKey, singleton, unions) import Data.Void         (Void)-import Gauge             (bench, bgroup, defaultMain, env, nf, nfIO, whnf)+import Gauge             (bench, bgroup, defaultMain, env, nf, whnf)  import System.Directory -import qualified Codec.Serialise import qualified Data.ByteString.Lazy import qualified Data.Text            as T import qualified Data.Text.IO         as TIO@@ -50,7 +49,7 @@  benchExprFromBytes     :: String -> Data.ByteString.Lazy.ByteString -> Gauge.Benchmark-benchExprFromBytes name bytes = bench name (nf f bytes)+benchExprFromBytes name bs = bench name (nf f bs)   where     f bytes =         case Dhall.Binary.decodeExpression bytes of
dhall-lang/Prelude/Bool/and.dhall view
@@ -1,4 +1,4 @@-{-+{-| The `and` function returns `False` if there are any `False` elements in the `List` and returns `True` otherwise -}
dhall-lang/Prelude/Bool/build.dhall view
@@ -1,6 +1,4 @@-{--`build` is the inverse of `fold`--}+--| `build` is the inverse of `fold` let build     : (∀(bool : Type) → ∀(true : bool) → ∀(false : bool) → bool) → Bool     = λ(f : ∀(bool : Type) → ∀(true : bool) → ∀(false : bool) → bool) →
dhall-lang/Prelude/Bool/even.dhall view
@@ -1,4 +1,4 @@-{-+{-| Returns `True` if there are an even number of `False` elements in the list and returns `False` otherwise. 
dhall-lang/Prelude/Bool/fold.dhall view
@@ -1,6 +1,4 @@-{--`fold` is essentially the same as `if`/`then`/`else` except as a function--}+--| `fold` is essentially the same as `if`/`then`/`else` except as a function let fold     : ∀(b : Bool) → ∀(bool : Type) → ∀(true : bool) → ∀(false : bool) → bool     = λ(b : Bool) →
dhall-lang/Prelude/Bool/not.dhall view
@@ -1,6 +1,4 @@-{--Flip the value of a `Bool`--}+--| Flip the value of a `Bool` let not     : Bool → Bool     = λ(b : Bool) → b == False
dhall-lang/Prelude/Bool/odd.dhall view
@@ -1,4 +1,4 @@-{-+{-| Returns `True` if there are an odd number of `True` elements in the list and returns `False` otherwise. 
dhall-lang/Prelude/Bool/or.dhall view
@@ -1,4 +1,4 @@-{-+{-| The `or` function returns `True` if there are any `True` elements in the `List` and returns `False` otherwise -}
dhall-lang/Prelude/Bool/show.dhall view
@@ -1,4 +1,4 @@-{-+{-| Render a `Bool` as `Text` using the same representation as Dhall source code (i.e. beginning with a capital letter) -}
dhall-lang/Prelude/Double/show.dhall view
@@ -1,4 +1,4 @@-{-+{-| Render a `Double` as `Text` using the same representation as Dhall source code (i.e. a decimal floating point number with a leading `-` sign if negative) -}
dhall-lang/Prelude/Function/compose.dhall view
@@ -1,6 +1,4 @@-{--Compose two functions into one.--}+--| Compose two functions into one. let compose     : ∀(a : Type) → ∀(b : Type) → ∀(c : Type) → (a → b) → (b → c) → a → c     = λ(A : Type) →
dhall-lang/Prelude/Function/identity.dhall view
@@ -1,6 +1,4 @@-{--The identity function simply returns its input--}+--| The identity function simply returns its input let identity     : ∀(a : Type) → ∀(x : a) → a     = λ(a : Type) → λ(x : a) → x
dhall-lang/Prelude/Integer/abs.dhall view
@@ -1,6 +1,4 @@-{--Returns the absolute value of an `Integer`, i.e. its non-negative value.--}+--| Returns the absolute value of an `Integer`, i.e. its non-negative value. let abs     : Integer → Natural     = λ(n : Integer) →
dhall-lang/Prelude/Integer/add.dhall view
@@ -1,6 +1,4 @@-{--`add m n` computes `m + n`.--}+--| `add m n` computes `m + n`. let Integer/subtract =         ./subtract sha256:a34d36272fa8ae4f1ec8b56222fe8dc8a2ec55ec6538b840de0cbe207b006fda       ? ./subtract
dhall-lang/Prelude/Integer/clamp.dhall view
@@ -1,4 +1,4 @@-{-+{-| Convert an `Integer` to a `Natural` number, with negative numbers becoming zero. -} let clamp
dhall-lang/Prelude/Integer/equal.dhall view
@@ -1,6 +1,4 @@-{--`equal` checks if two Integers are equal.--}+--| `equal` checks if two Integers are equal. let Natural/equal =         ../Natural/equal sha256:7f108edfa35ddc7cebafb24dc073478e93a802e13b5bc3fd22f4768c9b066e60       ? ../Natural/equal
dhall-lang/Prelude/Integer/greaterThan.dhall view
@@ -1,6 +1,4 @@-{--`greaterThan` checks if one Integer is greater than another.--}+--| `greaterThan` checks if one Integer is greater than another. let Bool/not =         ../Bool/not sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4       ? ../Bool/not
dhall-lang/Prelude/Integer/greaterThanEqual.dhall view
@@ -1,4 +1,4 @@-{-+{-| `greaterThanEqual` checks if one Integer is greater than or equal to another. -} let lessThanEqual =
dhall-lang/Prelude/Integer/lessThan.dhall view
@@ -1,6 +1,4 @@-{--`lessThan` checks if one Integer is less than another.--}+--| `lessThan` checks if one Integer is less than another. let greaterThan =         ./greaterThan sha256:d23affd73029fc9aaf867c2c7b86510ca2802d3f0d1f3e1d1a93ffd87b7cb64b       ? ./greaterThan
dhall-lang/Prelude/Integer/lessThanEqual.dhall view
@@ -1,6 +1,4 @@-{--`lessThanEqual` checks if one Integer is less than or equal to another.--}+--| `lessThanEqual` checks if one Integer is less than or equal to another. let Natural/greaterThanEqual =         ../Natural/greaterThanEqual sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4       ? ../Natural/greaterThanEqual
dhall-lang/Prelude/Integer/multiply.dhall view
@@ -1,6 +1,4 @@-{--`multiply m n` computes `m * n`.--}+--| `multiply m n` computes `m * n`.  let nonPositive =         ./nonPositive sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b
dhall-lang/Prelude/Integer/negate.dhall view
@@ -1,6 +1,4 @@-{--Invert the sign of an `Integer`, with zero remaining unchanged.--}+--| Invert the sign of an `Integer`, with zero remaining unchanged. let negate     : Integer → Integer     = Integer/negate
dhall-lang/Prelude/Integer/negative.dhall view
@@ -1,4 +1,4 @@-{-+{-| Returns `True` for any `Integer` less than `+0`.  `negative` is more efficient than `./lessThan +0` or `./lessThanEqual -1`.
dhall-lang/Prelude/Integer/nonNegative.dhall view
@@ -1,4 +1,4 @@-{-+{-| Returns `True` for `+0` and any positive `Integer`.  `nonNegative` is more efficient than `./greaterThanEqual +0` or `./greaterThan -1`.
dhall-lang/Prelude/Integer/nonPositive.dhall view
@@ -1,4 +1,4 @@-{-+{-| Returns `True` for `+0` and any negative `Integer`.  `nonPositive` is more efficient than `./lessThanEqual +0` or `./lessThan +1`.
dhall-lang/Prelude/Integer/positive.dhall view
@@ -1,4 +1,4 @@-{-+{-| Returns `True` for any `Integer` greater than `+0`.  `positive` is more efficient than `./greaterThan +0` or `./greaterThanEqual +1`.
dhall-lang/Prelude/Integer/show.dhall view
@@ -1,4 +1,4 @@-{-+{-| Render an `Integer` as `Text` using the same representation as Dhall source code (i.e. a decimal number with a leading `-` sign if negative and a leading `+` sign if non-negative)
dhall-lang/Prelude/Integer/subtract.dhall view
@@ -1,6 +1,4 @@-{--`subtract m n` computes `n - m`.--}+--| `subtract m n` computes `n - m`. let nonPositive =         ./nonPositive sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b       ? ./nonPositive
dhall-lang/Prelude/Integer/toDouble.dhall view
@@ -1,6 +1,4 @@-{--Convert an `Integer` to the corresponding `Double`--}+--| Convert an `Integer` to the corresponding `Double` let toDouble     : Integer → Double     = Integer/toDouble
dhall-lang/Prelude/Integer/toNatural.dhall view
@@ -1,4 +1,4 @@-{-+{-| Convert an `Integer` to an `Optional Natural`, with negative numbers becoming `None Natural`. -} let nonNegative =
dhall-lang/Prelude/JSON/Format.dhall view
@@ -1,7 +1,8 @@-{- An internal type used by `./renderAs` to select the output format.+{-|+An internal type used by `./renderAs` to select the output format. -   You should not need to use this type directly, simply use `./render`-   or `./renderYAML` as appropriate.+You should not need to use this type directly, simply use `./render`+or `./renderYAML` as appropriate. -}  < YAML | JSON >
dhall-lang/Prelude/JSON/Nesting.dhall view
@@ -1,4 +1,4 @@-{-+{-| This type is used as part of `dhall-json`'s support for preserving alternative names @@ -24,7 +24,7 @@ {   "foo": 2,   "name": "Left"- }+} ```  -}
dhall-lang/Prelude/JSON/Tagged.dhall view
@@ -1,4 +1,4 @@-{-+{-| This is a convenient type-level function when using `dhall-to-json`'s support for preserving alternative names 
dhall-lang/Prelude/JSON/Type.dhall view
@@ -1,12 +1,13 @@-{- Dhall encoding of an arbitrary JSON value+{-|+Dhall encoding of an arbitrary JSON value -   For example, the following JSON value:+For example, the following JSON value:  ``` [ { "foo": null, "bar": [ 1.0, true ] } ] ``` -   ... corresponds to the following Dhall expression:+... corresponds to the following Dhall expression:  ``` λ(JSON : Type) →
dhall-lang/Prelude/JSON/array.dhall view
@@ -1,4 +1,5 @@-{- Create a JSON array from a `List` of JSON values+{-|+Create a JSON array from a `List` of JSON values  ``` let JSON = ./package.dhall
dhall-lang/Prelude/JSON/bool.dhall view
@@ -1,4 +1,5 @@-{- Create a JSON bool from a Dhall `Bool`+{-|+Create a JSON bool from a Dhall `Bool`  ``` let JSON = ./package.dhall
dhall-lang/Prelude/JSON/core.dhall view
@@ -1,12 +1,11 @@-{- A record of functions useful for constructing `JSON` values.+{-|+A record of functions useful for constructing `JSON` values. -   This is only a subset of what `package.dhall` exports. If you are-   not writing a JSON prelude function, you should use the-   `package.dhall` file instead.+This is only a subset of what `package.dhall` exports. If you are not writing a+JSON prelude function, you should use the `package.dhall` file instead. -   It is used internally by `render`, `renderYAML` and-   `omitNullFields` instead of `package.dhall` to avoid import-   cycles.+It is used internally by `render`, `renderYAML` and `omitNullFields` instead of+`package.dhall` to avoid import cycles. -} { Type =       ./Type sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759
dhall-lang/Prelude/JSON/double.dhall view
@@ -1,4 +1,5 @@-{- Create a JSON number from a Dhall `Double`+{-|+Create a JSON number from a Dhall `Double`  ``` let JSON = ./package.dhall
dhall-lang/Prelude/JSON/integer.dhall view
@@ -1,4 +1,5 @@-{- Create a JSON number from a Dhall `Integer`+{-|+Create a JSON number from a Dhall `Integer`  ``` let JSON = ./package.dhall
dhall-lang/Prelude/JSON/natural.dhall view
@@ -1,4 +1,5 @@-{- Create a JSON number from a Dhall `Natural`+{-|+Create a JSON number from a Dhall `Natural`  ``` let JSON = ./package.dhall
dhall-lang/Prelude/JSON/null.dhall view
@@ -1,4 +1,5 @@-{- Create a JSON null+{-|+Create a JSON null  ``` let JSON = ./package.dhall
dhall-lang/Prelude/JSON/number.dhall view
@@ -1,4 +1,5 @@-{- Create a JSON number from a Dhall `Double`+{-|+Create a JSON number from a Dhall `Double`  ``` let JSON = ./package.dhall
dhall-lang/Prelude/JSON/object.dhall view
@@ -1,4 +1,5 @@-{- Create a JSON object from a Dhall `Map`+{-|+Create a JSON object from a Dhall `Map`  ``` let JSON = ./package.dhall
dhall-lang/Prelude/JSON/omitNullFields.dhall view
@@ -1,4 +1,4 @@-{-+{-| This utility omits all `null` record fields, which is often the idiomatic way for a configuration to encode absent fields -}
dhall-lang/Prelude/JSON/render.dhall view
@@ -1,8 +1,8 @@-{- Render a `JSON` value as `Text`--   This is useful for debugging `JSON` values or for tests.  For anything-   more sophisticated you should use `dhall-to-json` or `dhall-to-yaml`+{-|+Render a `JSON` value as `Text` +This is useful for debugging `JSON` values or for tests.  For anything+more sophisticated you should use `dhall-to-json` or `dhall-to-yaml` -} let JSON =         ./core.dhall sha256:5dc1135d5481cfd6fde625aaed9fcbdb7aa7c14f2e76726aa5fdef028a5c10f5
dhall-lang/Prelude/JSON/renderAs.dhall view
@@ -1,4 +1,4 @@-{- Render a `JSON` value as `Text` in either JSON or YAML format. -}+--| Render a `JSON` value as `Text` in either JSON or YAML format.  let JSON =         ./core.dhall sha256:5dc1135d5481cfd6fde625aaed9fcbdb7aa7c14f2e76726aa5fdef028a5c10f5
dhall-lang/Prelude/JSON/renderInteger.dhall view
@@ -1,5 +1,6 @@-{- Render an `Integer` value as a `JSON number`, according to the JSON-   standard, in which a number may not start with a plus sign (`+`).+{-|+Render an `Integer` value as a `JSON number`, according to the JSON standard, in+which a number may not start with a plus sign (`+`). -}  let Integer/nonNegative =
dhall-lang/Prelude/JSON/renderYAML.dhall view
@@ -1,12 +1,12 @@-{- Render a `JSON` value as `Text` in YAML format.--   The generated YAML text will only contain escaped object keys and-   string values and might therefore not be very human readable.+{-|+Render a `JSON` value as `Text` in YAML format. -   However, it is useful for debugging `JSON` values or for tests.-   For anything more sophisticated you should use `dhall-to-json` or-   `dhall-to-yaml`.+The generated YAML text will only contain escaped object keys and+string values and might therefore not be very human readable. +However, it is useful for debugging `JSON` values or for tests.+For anything more sophisticated you should use `dhall-to-json` or+`dhall-to-yaml`. -}  let JSON =
dhall-lang/Prelude/JSON/string.dhall view
@@ -1,4 +1,5 @@-{- Create a JSON string from Dhall `Text`+{-|+Create a JSON string from Dhall `Text`  ``` let JSON = ./package.dhall
dhall-lang/Prelude/JSON/tagInline.dhall view
@@ -1,5 +1,4 @@-{- Prepare a union value for JSON- or YAML-encoding with the inline layout--}+--| Prepare a union value for JSON- or YAML-encoding with the inline layout let Nesting =         ./Nesting sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335       ? ./Nesting
dhall-lang/Prelude/JSON/tagNested.dhall view
@@ -1,5 +1,4 @@-{- Prepare a union value for JSON- or YAML-encoding with the nested layout--}+--| Prepare a union value for JSON- or YAML-encoding with the nested layout let Nesting =         ./Nesting sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335       ? ./Nesting
dhall-lang/Prelude/List/all.dhall view
@@ -1,4 +1,4 @@-{-+{-| Returns `True` if the supplied function returns `True` for all elements in the `List` -}
dhall-lang/Prelude/List/any.dhall view
@@ -1,4 +1,4 @@-{-+{-| Returns `True` if the supplied function returns `True` for any element in the `List` -}
dhall-lang/Prelude/List/build.dhall view
@@ -1,6 +1,4 @@-{--`build` is the inverse of `fold`--}+--| `build` is the inverse of `fold` let build     : ∀(a : Type) →       (∀(list : Type) → ∀(cons : a → list → list) → ∀(nil : list) → list) →
dhall-lang/Prelude/List/concat.dhall view
@@ -1,6 +1,4 @@-{--Concatenate a `List` of `List`s into a single `List`--}+--| Concatenate a `List` of `List`s into a single `List` let concat     : ∀(a : Type) → List (List a) → List a     = λ(a : Type) →
dhall-lang/Prelude/List/concatMap.dhall view
@@ -1,4 +1,4 @@-{-+{-| Transform a list by applying a function to each element and flattening the results -}
dhall-lang/Prelude/List/default.dhall view
@@ -1,4 +1,4 @@-{-+{-| Unpack an `Optional` containing a `List`, defaulting to an empty list when the `Optional` is `None` -}
dhall-lang/Prelude/List/drop.dhall view
@@ -1,4 +1,4 @@--- Remove first `n` elements of a list+--| Remove first `n` elements of a list let Natural/greaterThanEqual =         ../Natural/greaterThanEqual sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4       ? ../Natural/greaterThanEqual
dhall-lang/Prelude/List/empty.dhall view
@@ -1,6 +1,4 @@-{--An empty list of the given type--}+--| An empty list of the given type let empty     : ∀(a : Type) → List a     = λ(a : Type) → [] : List a
dhall-lang/Prelude/List/filter.dhall view
@@ -1,8 +1,4 @@-{--Only keep elements of the list where the supplied function returns `True`--Examples:--}+--| Only keep elements of the list where the supplied function returns `True` let filter     : ∀(a : Type) → (a → Bool) → List a → List a     = λ(a : Type) →
dhall-lang/Prelude/List/fold.dhall view
@@ -1,4 +1,4 @@-{-+{-| `fold` is the primitive function for consuming `List`s  If you treat the list `[ x, y, z ]` as `cons x (cons y (cons z nil))`, then a
dhall-lang/Prelude/List/generate.dhall view
@@ -1,4 +1,4 @@-{-+{-| Build a list by calling the supplied function on all `Natural` numbers from `0` up to but not including the supplied `Natural` number -}
dhall-lang/Prelude/List/head.dhall view
@@ -1,6 +1,4 @@-{--Retrieve the first element of the list--}+--| Retrieve the first element of the list let head     : ∀(a : Type) → List a → Optional a     = List/head
dhall-lang/Prelude/List/index.dhall view
@@ -1,6 +1,4 @@-{--Retrieve an element from a `List` using its 0-based index--}+--| Retrieve an element from a `List` using its 0-based index let drop =         ./drop sha256:af983ba3ead494dd72beed05c0f3a17c36a4244adedf7ced502c6512196ed0cf       ? ./drop
dhall-lang/Prelude/List/indexed.dhall view
@@ -1,6 +1,4 @@-{--Tag each element of the list with its index--}+--| Tag each element of the list with its index let indexed     : ∀(a : Type) → List a → List { index : Natural, value : a }     = List/indexed
dhall-lang/Prelude/List/iterate.dhall view
@@ -1,4 +1,4 @@-{-+{-| Generate a list of the specified length given a seed value and transition function -}
dhall-lang/Prelude/List/last.dhall view
@@ -1,6 +1,4 @@-{--Retrieve the last element of the list--}+--| Retrieve the last element of the list let last     : ∀(a : Type) → List a → Optional a     = List/last
dhall-lang/Prelude/List/length.dhall view
@@ -1,6 +1,4 @@-{--Returns the number of elements in a list--}+--| Returns the number of elements in a list let length     : ∀(a : Type) → List a → Natural     = List/length
dhall-lang/Prelude/List/map.dhall view
@@ -1,6 +1,4 @@-{--Transform a list by applying a function to each element--}+--| Transform a list by applying a function to each element let map     : ∀(a : Type) → ∀(b : Type) → (a → b) → List a → List b     = λ(a : Type) →
dhall-lang/Prelude/List/null.dhall view
@@ -1,6 +1,4 @@-{--Returns `True` if the `List` is empty and `False` otherwise--}+--| Returns `True` if the `List` is empty and `False` otherwise let null     : ∀(a : Type) → List a → Bool     = λ(a : Type) → λ(xs : List a) → Natural/isZero (List/length a xs)
dhall-lang/Prelude/List/partition.dhall view
@@ -1,4 +1,4 @@-{-+{-| `partition` divides a `List` of elements into those that satisfy a predicate and those that do not -}
dhall-lang/Prelude/List/replicate.dhall view
@@ -1,6 +1,4 @@-{--Build a list by copying the given element the specified number of times--}+--| Build a list by copying the given element the specified number of times let replicate     : Natural → ∀(a : Type) → a → List a     = λ(n : Natural) →
dhall-lang/Prelude/List/reverse.dhall view
@@ -1,6 +1,4 @@-{--Reverse a list--}+--| Reverse a list let reverse     : ∀(a : Type) → List a → List a     = List/reverse
dhall-lang/Prelude/List/shifted.dhall view
@@ -1,4 +1,4 @@-{-+{-| Combine a `List` of `List`s, offsetting the `index` of each element by the number of elements in preceding lists -}
dhall-lang/Prelude/List/take.dhall view
@@ -1,4 +1,4 @@--- Truncate a list to the first `n` elements+--| Truncate a list to the first `n` elements let Natural/lessThan =         ../Natural/lessThan sha256:3381b66749290769badf8855d8a3f4af62e8de52d1364d838a9d1e20c94fa70c       ? ../Natural/lessThan
dhall-lang/Prelude/List/unpackOptionals.dhall view
@@ -1,6 +1,4 @@-{--Unpack Optionals in a List, omitting None items.--}+--| Unpack Optionals in a List, omitting None items.  let List/concatMap =         ./concatMap sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64
dhall-lang/Prelude/List/unzip.dhall view
@@ -1,6 +1,4 @@-{--Unzip a `List` into two separate `List`s--}+--| Unzip a `List` into two separate `List`s let unzip     : ∀(a : Type) →       ∀(b : Type) →
dhall-lang/Prelude/List/zip.dhall view
@@ -1,7 +1,7 @@-{-+{-| Zip two `List` into a single `List` -Resulting `List` will have the length of the shortest of its arguments.+The resulting `List` will have the length of the shortest of its arguments. -} let List/index =         ./index sha256:e657b55ecae4d899465c3032cb1a64c6aa6dc2aa3034204f3c15ce5c96c03e63
dhall-lang/Prelude/Location/Type.dhall view
@@ -1,5 +1,4 @@-{- This is the union type returned when you import something `as Location`--}+--| This is the union type returned when you import something `as Location` let Location     : Type     = < Environment : Text | Local : Text | Missing | Remote : Text >
dhall-lang/Prelude/Map/Entry.dhall view
@@ -1,5 +1,4 @@-{- The type of each key-value pair in a `Map`--}+--| The type of each key-value pair in a `Map` let Entry     : Type → Type → Type     = λ(k : Type) → λ(v : Type) → { mapKey : k, mapValue : v }
dhall-lang/Prelude/Map/Type.dhall view
@@ -1,21 +1,22 @@-{- This is the canonical way to encode a dynamic list of key-value pairs.+{-|+This is the canonical way to encode a dynamic list of key-value pairs. -   Tools (such as `dhall-to-json`/`dhall-to-yaml` will recognize values of this-   type and convert them to maps/dictionaries/hashes in the target language+Tools (such as `dhall-to-json`/`dhall-to-yaml` will recognize values of this+type and convert them to maps/dictionaries/hashes in the target language -   For example, `dhall-to-json` converts a Dhall value like this:+For example, `dhall-to-json` converts a Dhall value like this: -   ```-   [ { mapKey = "foo", mapValue = 1 }-   , { mapKey = "bar", mapValue = 2 }-   ] : ./Map Text Natural-   ```+```+[ { mapKey = "foo", mapValue = 1 }+, { mapKey = "bar", mapValue = 2 }+] : ./Map Text Natural+``` -   ... to a JSON value like this:+... to a JSON value like this: -   ```-   { "foo": 1, "bar", 2 }-   ```+```+{ "foo": 1, "bar", 2 }+``` -} let Map     : Type → Type → Type
dhall-lang/Prelude/Map/empty.dhall view
@@ -1,6 +1,4 @@-{--An empty `Map` of the given key and value types--}+--| An empty `Map` of the given key and value types let Map =         ./Type sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed       ? ./Type
dhall-lang/Prelude/Map/keyText.dhall view
@@ -1,4 +1,4 @@-{-+{-| Builds a key-value record such that a `List` of them will be converted to a homogeneous record by dhall-to-json and dhall-to-yaml. 
dhall-lang/Prelude/Map/keyValue.dhall view
@@ -1,4 +1,4 @@-{-+{-| Builds a key-value record such that a List of them will be converted to a homogeneous record by dhall-to-json and dhall-to-yaml. -}
dhall-lang/Prelude/Map/keys.dhall view
@@ -1,6 +1,4 @@-{--Get all of the keys of a `Map` as a `List`--}+--| Get all of the keys of a `Map` as a `List` let Map =         ./Type sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed       ? ./Type
dhall-lang/Prelude/Map/map.dhall view
@@ -1,6 +1,4 @@-{--Transform a `Map` by applying a function to each value--}+--| Transform a `Map` by applying a function to each value let Map =         ./Type sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed       ? ./Type
dhall-lang/Prelude/Map/values.dhall view
@@ -1,6 +1,4 @@-{--Get all of the values of a `Map` as a `List`--}+--| Get all of the values of a `Map` as a `List` let Map =         ./Type sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed       ? ./Type
dhall-lang/Prelude/Monoid.dhall view
@@ -1,4 +1,4 @@-{-+{-| Any function `f` that is a `Monoid` must satisfy the following law:  ```
dhall-lang/Prelude/Natural/build.dhall view
@@ -1,6 +1,4 @@-{--`build` is the inverse of `fold`--}+--| `build` is the inverse of `fold` let build     : ( ∀(natural : Type) →         ∀(succ : natural → natural) →
dhall-lang/Prelude/Natural/enumerate.dhall view
@@ -1,4 +1,4 @@-{-+{-| Generate a list of numbers from `0` up to but not including the specified number -}
dhall-lang/Prelude/Natural/equal.dhall view
@@ -1,6 +1,4 @@-{--`equal` checks if two Naturals are equal.--}+--| `equal` checks if two Naturals are equal. let lessThanEqual =         ./lessThanEqual sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99       ? ./lessThanEqual
dhall-lang/Prelude/Natural/even.dhall view
@@ -1,6 +1,4 @@-{--Returns `True` if a number if even and returns `False` otherwise--}+--| Returns `True` if a number if even and returns `False` otherwise let even     : Natural → Bool     = Natural/even
dhall-lang/Prelude/Natural/fold.dhall view
@@ -1,4 +1,4 @@-{-+{-| `fold` is the primitive function for consuming `Natural` numbers  If you treat the number `3` as `succ (succ (succ zero))` then a `fold` just
dhall-lang/Prelude/Natural/greaterThan.dhall view
@@ -1,6 +1,4 @@-{--`greaterThan` checks if one Natural is strictly greater than another.--}+--| `greaterThan` checks if one Natural is strictly greater than another. let lessThan =         ./lessThan sha256:3381b66749290769badf8855d8a3f4af62e8de52d1364d838a9d1e20c94fa70c       ? ./lessThan
dhall-lang/Prelude/Natural/greaterThanEqual.dhall view
@@ -1,4 +1,4 @@-{-+{-| `greaterThanEqual` checks if one Natural is greater than or equal to another. -} let lessThanEqual =
dhall-lang/Prelude/Natural/isZero.dhall view
@@ -1,6 +1,4 @@-{--Returns `True` if a number is `0` and returns `False` otherwise--}+--| Returns `True` if a number is `0` and returns `False` otherwise let isZero     : Natural → Bool     = Natural/isZero
dhall-lang/Prelude/Natural/lessThan.dhall view
@@ -1,6 +1,4 @@-{--`lessThan` checks if one Natural is strictly less than another.--}+--| `lessThan` checks if one Natural is strictly less than another. let greaterThanEqual =         ./greaterThanEqual sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4       ? ./greaterThanEqual
dhall-lang/Prelude/Natural/lessThanEqual.dhall view
@@ -1,6 +1,4 @@-{--`lessThanEqual` checks if one Natural is less than or equal to another.--}+--| `lessThanEqual` checks if one Natural is less than or equal to another. let lessThanEqual     : Natural → Natural → Bool     = λ(x : Natural) → λ(y : Natural) → Natural/isZero (Natural/subtract y x)
dhall-lang/Prelude/Natural/listMax.dhall view
@@ -1,4 +1,4 @@-{-+{-| `listMax` returns the largest element of a `List` or `None Natural` if the `List` is empty -}
dhall-lang/Prelude/Natural/listMin.dhall view
@@ -1,4 +1,4 @@-{-+{-| `listMin` returns the smallest element of a `List` or `None Natural` if the `List` is empty -}
dhall-lang/Prelude/Natural/max.dhall view
@@ -1,6 +1,4 @@-{--`max a b` returns the larger of `a` or `b`--}+--| `max a b` returns the larger of `a` or `b` let lessThanEqual =         ./lessThanEqual sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99       ? ./lessThanEqual
dhall-lang/Prelude/Natural/min.dhall view
@@ -1,6 +1,4 @@-{--`min a b` returns the smaller of `a` or `b`--}+--| `min a b` returns the smaller of `a` or `b` let lessThanEqual =         ./lessThanEqual sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99       ? ./lessThanEqual
dhall-lang/Prelude/Natural/odd.dhall view
@@ -1,6 +1,4 @@-{--Returns `True` if a number is odd and returns `False` otherwise--}+--| Returns `True` if a number is odd and returns `False` otherwise let odd     : Natural → Bool     = Natural/odd
dhall-lang/Prelude/Natural/product.dhall view
@@ -1,6 +1,4 @@-{--Multiply all the numbers in a `List`--}+--| Multiply all the numbers in a `List` let product     : List Natural → Natural     = λ(xs : List Natural) →
dhall-lang/Prelude/Natural/show.dhall view
@@ -1,4 +1,4 @@-{-+{-| Render a `Natural` number as `Text` using the same representation as Dhall source code (i.e. a decimal number) -}
dhall-lang/Prelude/Natural/sort.dhall view
@@ -1,6 +1,4 @@-{--`sort` sorts a `List` of `Natural`s in ascending order--}+--| `sort` sorts a `List` of `Natural`s in ascending order let greaterThanEqual =         ./greaterThanEqual sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4       ? ./greaterThanEqual
dhall-lang/Prelude/Natural/subtract.dhall view
@@ -1,6 +1,4 @@-{--`subtract m n` computes `n - m`, truncating to `0` if `m > n`--}+--| `subtract m n` computes `n - m`, truncating to `0` if `m > n` let subtract     : Natural → Natural → Natural     = Natural/subtract
dhall-lang/Prelude/Natural/sum.dhall view
@@ -1,6 +1,4 @@-{--Add all the numbers in a `List`--}+--| Add all the numbers in a `List` let sum     : List Natural → Natural     = λ(xs : List Natural) →
dhall-lang/Prelude/Natural/toDouble.dhall view
@@ -1,6 +1,4 @@-{--Convert a `Natural` number to the corresponding `Double`--}+--| Convert a `Natural` number to the corresponding `Double` let toDouble     : Natural → Double     = λ(n : Natural) → Integer/toDouble (Natural/toInteger n)
dhall-lang/Prelude/Natural/toInteger.dhall view
@@ -1,6 +1,4 @@-{--Convert a `Natural` number to the corresponding `Integer`--}+--| Convert a `Natural` number to the corresponding `Integer` let toInteger     : Natural → Integer     = Natural/toInteger
dhall-lang/Prelude/Optional/all.dhall view
@@ -1,4 +1,4 @@-{-+{-| Returns `False` if the supplied function returns `False` for a present element and `True` otherwise: -}
dhall-lang/Prelude/Optional/any.dhall view
@@ -1,4 +1,4 @@-{-+{-| Returns `True` if the supplied function returns `True` for a present element and `False` otherwise -}
dhall-lang/Prelude/Optional/build.dhall view
@@ -1,6 +1,4 @@-{--`build` is the inverse of `fold`--}+--| `build` is the inverse of `fold` let build     : ∀(a : Type) →       ( ∀(optional : Type) →
dhall-lang/Prelude/Optional/concat.dhall view
@@ -1,6 +1,4 @@-{--Flatten two `Optional` layers into a single `Optional` layer--}+--| Flatten two `Optional` layers into a single `Optional` layer let concat     : ∀(a : Type) → Optional (Optional a) → Optional a     = λ(a : Type) →
dhall-lang/Prelude/Optional/default.dhall view
@@ -1,6 +1,4 @@-{--Unpack an `Optional`, returning the default when it's `None`.--}+--| Unpack an `Optional`, returning the default when it's `None`. let default     : ∀(a : Type) → a → Optional a → a     = λ(a : Type) →
dhall-lang/Prelude/Optional/filter.dhall view
@@ -1,6 +1,4 @@-{--Only keep an `Optional` element if the supplied function returns `True`--}+--| Only keep an `Optional` element if the supplied function returns `True` let filter     : ∀(a : Type) → (a → Bool) → Optional a → Optional a     = λ(a : Type) →
dhall-lang/Prelude/Optional/fold.dhall view
@@ -1,6 +1,4 @@-{--`fold` is the primitive function for consuming `Optional` values--}+--| `fold` is the primitive function for consuming `Optional` values let fold     : ∀(a : Type) →       Optional a →
dhall-lang/Prelude/Optional/head.dhall view
@@ -1,6 +1,4 @@-{--Returns the first non-empty `Optional` value in a `List`--}+--| Returns the first non-empty `Optional` value in a `List` let head     : ∀(a : Type) → List (Optional a) → Optional a     = λ(a : Type) →
dhall-lang/Prelude/Optional/last.dhall view
@@ -1,6 +1,4 @@-{--Returns the last non-empty `Optional` value in a `List`--}+--| Returns the last non-empty `Optional` value in a `List` let last     : ∀(a : Type) → List (Optional a) → Optional a     = λ(a : Type) →
dhall-lang/Prelude/Optional/length.dhall view
@@ -1,4 +1,4 @@-{-+{-| Returns `1` if the `Optional` value is present and `0` if the value is absent -} let length
dhall-lang/Prelude/Optional/map.dhall view
@@ -1,6 +1,4 @@-{--Transform an `Optional` value with a function--}+--| Transform an `Optional` value with a function let map     : ∀(a : Type) → ∀(b : Type) → (a → b) → Optional a → Optional b     = λ(a : Type) →
dhall-lang/Prelude/Optional/null.dhall view
@@ -1,6 +1,4 @@-{--Returns `True` if the `Optional` value is absent and `False` if present--}+--| Returns `True` if the `Optional` value is absent and `False` if present let null     : ∀(a : Type) → Optional a → Bool     = λ(a : Type) →
dhall-lang/Prelude/Optional/toList.dhall view
@@ -1,6 +1,4 @@-{--Convert an `Optional` value into the equivalent `List`--}+--| Convert an `Optional` value into the equivalent `List` let toList     : ∀(a : Type) → Optional a → List a     = λ(a : Type) →
dhall-lang/Prelude/Optional/unzip.dhall view
@@ -1,6 +1,4 @@-{--Unzip an `Optional` value into two separate `Optional` values--}+--| Unzip an `Optional` value into two separate `Optional` values let unzip     : ∀(a : Type) →       ∀(b : Type) →
dhall-lang/Prelude/Text/concat.dhall view
@@ -1,6 +1,4 @@-{--Concatenate all the `Text` values in a `List`--}+--| Concatenate all the `Text` values in a `List` let concat     : List Text → Text     = λ(xs : List Text) →
dhall-lang/Prelude/Text/concatMap.dhall view
@@ -1,6 +1,4 @@-{--Transform each value in a `List` into `Text` and concatenate the result--}+--| Transform each value in a `List` into `Text` and concatenate the result let concatMap     : ∀(a : Type) → (a → Text) → List a → Text     = λ(a : Type) →
dhall-lang/Prelude/Text/concatMapSep.dhall view
@@ -1,4 +1,4 @@-{-+{-| Transform each value in a `List` to `Text` and then concatenate them with a separator in between each value -}
dhall-lang/Prelude/Text/concatSep.dhall view
@@ -1,6 +1,4 @@-{--Concatenate a `List` of `Text` values with a separator in between each value--}+--| Concatenate a `List` of `Text` values with a separator in between each value let Status = < Empty | NonEmpty : Text >  let concatSep
dhall-lang/Prelude/Text/default.dhall view
@@ -1,6 +1,4 @@-{--Unwrap an `Optional` `Text` value, defaulting `None` to `""`--}+--| Unwrap an `Optional` `Text` value, defaulting `None` to `""` let default     : Optional Text → Text     = λ(o : Optional Text) → merge { Some = λ(t : Text) → t, None = "" } o
dhall-lang/Prelude/Text/defaultMap.dhall view
@@ -1,6 +1,4 @@-{--Transform the value in an `Optional` into `Text`, defaulting `None` to `""`--}+--| Transform the value in an `Optional` into `Text`, defaulting `None` to `""` let defaultMap     : ∀(a : Type) → (a → Text) → Optional a → Text     = λ(a : Type) →
dhall-lang/Prelude/Text/replicate.dhall view
@@ -1,6 +1,4 @@-{--Build a Text by copying the given Text the specified number of times--}+--| Build a Text by copying the given Text the specified number of times  let concat =         ./concat sha256:731265b0288e8a905ecff95c97333ee2db614c39d69f1514cb8eed9259745fc0
dhall-lang/Prelude/Text/spaces.dhall view
@@ -1,8 +1,8 @@-{-+{-| Return a Text with the number of spaces specified. -This function is particularly helpful when trying to generate Text where whitespace-is significant, i.e. with nested indentation.+This function is particularly helpful when trying to generate Text where+whitespace is significant, i.e. with nested indentation. -}  let replicate =
dhall-lang/Prelude/XML/Type.dhall view
@@ -1,12 +1,13 @@-{- Dhall encoding of an arbitrary XML element+{-|+Dhall encoding of an arbitrary XML element -   For example, the following XML element:+For example, the following XML element:  ``` <foo n="1"><bar>baz</bar></foo> ``` -   ... corresponds to the following Dhall expression:+... corresponds to the following Dhall expression:   ```
dhall-lang/Prelude/XML/attribute.dhall view
@@ -1,4 +1,4 @@-{- Builds a key-value record with a Text key and value. -}+--| Builds a key-value record with a Text key and value.  let attribute     : Text → Text → { mapKey : Text, mapValue : Text }
dhall-lang/Prelude/XML/element.dhall view
@@ -1,4 +1,5 @@-{- Create an XML element value.+{-|+Create an XML element value.  ``` let XML = ./package.dhall
dhall-lang/Prelude/XML/emptyAttributes.dhall view
@@ -1,3 +1,3 @@-{- Create an empty XML attribute List. -}+--| Create an empty XML attribute List.  [] : List { mapKey : Text, mapValue : Text }
dhall-lang/Prelude/XML/leaf.dhall view
@@ -1,4 +1,5 @@-{- Create an XML element value without child elements.+{-|+Create an XML element value without child elements.  ``` let XML = ./package.dhall
dhall-lang/Prelude/XML/render.dhall view
@@ -1,11 +1,12 @@-{- Render an `XML` value as `Text`+{-|+Render an `XML` value as `Text` -   *WARNING:* rendering does not include any XML injection mitigations,-   therefore it should not be used to process arbitrary strings into-   element attributes or element data.+*WARNING:* rendering does not include any XML injection mitigations,+therefore it should not be used to process arbitrary strings into+element attributes or element data. -   For indentation and schema validation, see the `xmllint` utility-   bundled with libxml2.+For indentation and schema validation, see the `xmllint` utility+bundled with libxml2.  ``` let XML = ./package.dhall
dhall-lang/Prelude/XML/text.dhall view
@@ -1,4 +1,5 @@-{- Create a Text value to be inserted into an XML element as content.+{-|+Create a Text value to be inserted into an XML element as content.  ``` let XML = ./package.dhall
+ dhall-lang/tests/normalization/success/unit/WithDesugarA.dhall view
@@ -0,0 +1,4 @@+{- This test verifies that an implementation desugars `with` correctly by+   leaving `x` abstract+-}+\(x: { a : { b : { c : {} } }}) -> x with a.b.c = 42
+ dhall-lang/tests/normalization/success/unit/WithDesugarB.dhall view
@@ -0,0 +1,1 @@+λ(x : { a : { b : { c : {} } } }) → x ⫽ { a = x.a ⫽ { b = x.a.b ⫽ { c = 42 } } }
+ dhall-lang/tests/normalization/success/unit/WithUnderscoreA.dhall view
@@ -0,0 +1,5 @@+{- This test checks that an implementation doesn't mistakenly implement the+   optimization suggested by the standard without the requisite shift+   judgment+-}+let _ = 1 in {=} with a = _
+ dhall-lang/tests/normalization/success/unit/WithUnderscoreB.dhall view
@@ -0,0 +1,1 @@+{ a = 1 }
dhall-lang/tests/parser/success/unit/WithA.dhall view
@@ -1,6 +1,1 @@-{-  The purpose of this test is to verify that an implementation correctly-    desugars the base case of a non-nested update.  Specifically, an-    implementation should not use an intermediate `let` when desugaring this-    base case.--} { a = 1 } with a = 2
dhall-lang/tests/parser/success/unit/WithB.dhallb view
@@ -1,1 +1,1 @@-„	‚¡aa‚‚¡aa‚+„‚¡aa‚aa‚
dhall-lang/tests/parser/success/unit/WithMultipleA.dhall view
@@ -1,8 +1,4 @@-{- This test ensures that `with` is purely syntactic sugar, meaning that it is-   desugared before encoding and therefore is encoded as the desugared expression-   in the CBOR encoding.--   This test also ensures that implementations desugar the code exactly as-   specified (e.g. using an intermediate `let` binding)+{- This test verifies that an implementation correctly encodes chained+   `with` expressions in a left-associative way. -} { a.b = 1, c.d = 2 } with a.b = 3 with c.e = 4
dhall-lang/tests/parser/success/unit/WithMultipleB.dhallb view
@@ -1,1 +1,1 @@-„	„	‚¢aa‚¡ab‚ac‚¡ad‚‚¡aa„	ƒ	‚¢aa‚¡ab‚ac‚¡ad‚aa‚¡ab‚‚¡ac„	ƒ	„	‚¢aa‚¡ab‚ac‚¡ad‚‚¡aa„	ƒ	‚¢aa‚¡ab‚ac‚¡ad‚aa‚¡ab‚ac‚¡ae‚+„„‚¢aa‚¡ab‚ac‚¡ad‚‚aaab‚‚acae‚
dhall-lang/tests/parser/success/unit/WithPrecedence1B.dhallb view
@@ -1,1 +1,1 @@-„	„	‚¡aaƒö‚‚¡aaƒö‚‚¡aaƒö‚+„„‚¡aaƒö‚aaƒö‚aaƒö‚
dhall-lang/tests/parser/success/unit/WithPrecedence2B.dhallb view

binary file changed (25 → 23 bytes)

dhall-lang/tests/parser/success/unit/WithPrecedence3B.dhallb view

binary file changed (28 → 26 bytes)

+ dhall-lang/tests/type-inference/success/unit/WithNestedA.dhall view
@@ -0,0 +1,4 @@+{- This test illustrates that the `with` keyword is permitted to override+   existing fields nested within a child record+-}+{ a = { p = 2, q = "hi" }, b = 5.6 } with a.p = True
+ dhall-lang/tests/type-inference/success/unit/WithNestedB.dhall view
@@ -0,0 +1,1 @@+{ a : { p : Bool, q : Text }, b : Double }
dhall.cabal view
@@ -1,5 +1,5 @@ Name: dhall-Version: 1.34.0+Version: 1.35.0 Cabal-Version: >=1.10 Build-Type: Simple Tested-With: GHC == 8.4.3, GHC == 8.6.1@@ -455,6 +455,12 @@   Default:     True   Manual:      True +Flag use-http-client-tls+  Description: Use http-client-tls for resolving HTTP imports by default+               (requires with-http to be enabled)+  Default:     True+  Manual:      True+ Flag cross   Description: Disable TemplateHaskell to make cross-compiling easier   Default:     False@@ -466,7 +472,7 @@         base                        >= 4.11.0.0 && < 5   ,         aeson                       >= 1.0.0.0  && < 1.6 ,         aeson-pretty                               < 0.9 ,-        ansi-terminal               >= 0.6.3.1  && < 0.11,+        ansi-terminal               >= 0.6.3.1  && < 0.12,         atomic-write                >= 0.2.0.7  && < 0.3 ,         bytestring                                 < 0.11,         case-insensitive                           < 1.3 ,@@ -486,12 +492,12 @@         haskeline                   >= 0.7.2.1  && < 0.9 ,         hashable                    >= 1.2      && < 1.4 ,         lens-family-core            >= 1.0.0    && < 2.2 ,-        megaparsec                  >= 7        && < 8.1 ,+        megaparsec                  >= 7        && < 9.1 ,         memory                      >= 0.14     && < 0.16,         mmorph                                     < 1.2 ,         mtl                         >= 2.2.1    && < 2.3 ,         network-uri                 >= 2.6      && < 2.7 ,-        optparse-applicative        >= 0.14.0.0 && < 0.16,+        optparse-applicative        >= 0.14.0.0 && < 0.17,         parsers                     >= 0.12.4   && < 0.13,         parser-combinators                               ,         prettyprinter               >= 1.5.1    && < 1.8 ,@@ -513,6 +519,9 @@     if flag(with-http)       CPP-Options:         -DWITH_HTTP+      if flag(use-http-client-tls)+        CPP-Options:+          -DUSE_HTTP_CLIENT_TLS     if impl(ghcjs)       Hs-Source-Dirs: ghcjs-src       Build-Depends:@@ -525,8 +534,10 @@       if flag(with-http)         Build-Depends:           http-types                  >= 0.7.0    && < 0.13,-          http-client                 >= 0.5.0    && < 0.8 ,-          http-client-tls             >= 0.2.0    && < 0.4+          http-client                 >= 0.5.0    && < 0.8+        if flag(use-http-client-tls)+          Build-Depends:+            http-client-tls           >= 0.2.0    && < 0.4      Other-Extensions:         BangPatterns@@ -660,7 +671,6 @@         QuickCheck                >= 2.10     && < 2.15,         quickcheck-instances      >= 0.3.12   && < 0.4 ,         scientific                                     ,-        semigroups                                     ,         serialise                                      ,         special-values                           < 0.2 ,         spoon                                    < 0.4 ,@@ -668,6 +678,7 @@         tasty-expected-failure                   < 0.13,         tasty-hunit               >= 0.10     && < 0.11,         tasty-quickcheck          >= 0.9.2    && < 0.11,+        tasty-silver                             < 3.2 ,         template-haskell                               ,         text                      >= 0.11.1.0 && < 1.3 ,         transformers                                   ,@@ -703,12 +714,11 @@         dhall                                         ,         directory                                     ,         gauge                     >= 0.2.3    && < 0.3,-        serialise                                     ,         text                      >= 0.11.1.0 && < 1.3     Default-Language: Haskell2010     Other-Extensions:         TypeApplications-    ghc-options: -rtsopts+    ghc-options: -rtsopts -Wall  Benchmark deep-nested-large-record     Type: exitcode-stdio-1.0@@ -720,3 +730,4 @@         dhall                                         ,         gauge                     >= 0.2.3    && < 0.3     Default-Language: Haskell2010+    ghc-options: -Wall
doctest/Main.hs view
@@ -33,6 +33,7 @@          Test.DocTest.doctest             [ "-DWITH_HTTP"+            , "-DUSE_HTTP_CLIENT_TLS"             , "--fast"             , prefix </> "ghc-src" 
ghc-src/Dhall/Crypto.hs view
@@ -9,6 +9,7 @@       SHA256Digest(..)     , sha256DigestFromByteString     , sha256Hash+    , toString     ) where  import Control.DeepSeq         (NFData)@@ -26,7 +27,7 @@   deriving (Eq, Generic, Ord, NFData, ByteArrayAccess)  instance Show SHA256Digest where-  show (SHA256Digest bytes) = ByteString.Char8.unpack $ convertToBase Base16 bytes+  show = toString  {-| Attempt to interpret a `ByteString` as a `SHA256Digest`, returning     `Nothing` if the conversion fails@@ -41,3 +42,7 @@ sha256Hash bytes = SHA256Digest $ convert h   where     h = Crypto.Hash.hash bytes :: Crypto.Hash.Digest SHA256++-- | 'String' representation of a 'SHA256Digest'+toString :: SHA256Digest -> String+toString (SHA256Digest bytes) = ByteString.Char8.unpack $ convertToBase Base16 bytes
ghc-src/Dhall/Import/HTTP.hs view
@@ -25,7 +25,6 @@ import Network.HTTP.Client     ( HttpException (..)     , HttpExceptionContent (..)-    , Manager     )  import qualified Control.Exception@@ -37,7 +36,6 @@ import qualified Data.Text.Lazy.Encoding import qualified Dhall.Util import qualified Network.HTTP.Client              as HTTP-import qualified Network.HTTP.Client.TLS          as HTTP import qualified Network.HTTP.Types  mkPrettyHttpException :: String -> HttpException -> PrettyHttpException@@ -147,14 +145,11 @@  newManager :: StateT Status IO Manager newManager = do-    let settings = HTTP.tlsManagerSettings-          { HTTP.managerResponseTimeout = HTTP.responseTimeoutMicro (30 * 1000 * 1000) }  -- 30 seconds-     Status { _manager = oldManager, ..} <- State.get      case oldManager of         Nothing -> do-            manager <- liftIO (HTTP.newManager settings)+            manager <- liftIO _newManager              State.put (Status { _manager = Just manager , ..}) 
ghc-src/Dhall/Import/Manager.hs view
@@ -1,14 +1,33 @@-{-| Both the GHC and GHCJS implementations of "Dhall.Import.Manager" export a-    `Manager` type suitable for use within the "Dhall.Import" module+{-# LANGUAGE CPP #-} -    For the GHC implementation the `Manager` type is a real `Manager` from the-    @http-client@ package.  For the GHCJS implementation the `Manager` type is-    a synonym for @`Data.Void.Void`@ since GHCJS does not use a `Manager` for-    HTTP requests.+{-| Both the GHC and GHCJS implementations of 'Dhall.Import.Manager.Manager'+    export a `Dhall.Import.Manager.Manager` type suitable for use within the+    "Dhall.Import" module++    For the GHC implementation the `Dhall.Import.Manager` type is a real+    `Network.HTTP.Client.Manager` from the @http-client@ package.  For the+    GHCJS implementation the `Dhall.Import.Manager.Manager` type is+    a synonym for @`Data.Void.Void`@ since GHCJS does not use a+    `Network.HTTP.Client.Manager` for HTTP requests. -} module Dhall.Import.Manager     ( -- * Manager       Manager+    , defaultNewManager     ) where -import Network.HTTP.Client (Manager)+import Network.HTTP.Client (Manager, newManager)+import qualified Network.HTTP.Client as HTTP++#ifdef USE_HTTP_CLIENT_TLS+import Network.HTTP.Client.TLS (tlsManagerSettings)+#endif++defaultNewManager :: IO Manager+defaultNewManager = newManager+#ifdef USE_HTTP_CLIENT_TLS+  tlsManagerSettings+#else+  HTTP.defaultManagerSettings+#endif+    { HTTP.managerResponseTimeout = HTTP.responseTimeoutMicro (30 * 1000 * 1000) }  -- 30 seconds
ghcjs-src/Dhall/Import/HTTP.hs view
@@ -2,29 +2,18 @@  module Dhall.Import.HTTP     ( fetchFromHttpUrl-    , Manager     ) where  import Control.Monad.IO.Class           (MonadIO (..)) import Control.Monad.Trans.State.Strict (StateT) import Data.ByteString                  (ByteString) import Data.CaseInsensitive             (CI)-import Data.Void                        (Void) import Dhall.Core                       (URL (..))-import Dhall.Import.Types+import Dhall.Import.Types               (Status) import Dhall.URL                        (renderURL)  import qualified Data.Text      as Text import qualified JavaScript.XHR---{-| The GHCJS implementation does not require a `Manager`--    The purpose of this synonym is so that "Dhall.Import.Types" can import a-    `Manager` type from "Dhall.Import.HTTP" that does the correct thing for-    both the GHC and GHCJS implementations--}-type Manager = Void  fetchFromHttpUrl     :: URL
ghcjs-src/Dhall/Import/Manager.hs view
@@ -1,17 +1,26 @@-{-| Both the GHC and GHCJS implementations of "Dhall.Import.Manager" export a-    `Manager` type suitable for use within the "Dhall.Import" module+{-| Both the GHC and GHCJS implementations of `Dhall.Import.Manager.Manager`+    export a `Dhall.Import.Manager.Manager` type suitable for use within the+    "Dhall.Import" module -    For the GHC implementation the `Manager` type is a real `Manager` from the-    @http-client@ package.  For the GHCJS implementation the `Manager` type is-    a synonym for @`Data.Void.Void`@ since GHCJS does not use a `Manager` for-    HTTP requests.+    For the GHC implementation the `Dhall.Import.Manager.Manager` type is a real+    `Network.HTTP.Client.Manager` from the @http-client@ package.  For the GHCJS+    implementation the `Dhall.Import.Manager.Manager` type is a synonym for+    @`Data.Void.Void`@ since GHCJS does not use a+    `Network.HTTP.Client.Manager` for HTTP requests. -} module Dhall.Import.Manager     ( -- * Manager       Manager+    , defaultNewManager     ) where -import Data.Void (Void)+{-| The GHCJS implementation does not require a `Network.HTTP.Client.Manager` --- | GHCJS does not use a `Manager`-type Manager = Void+    The purpose of this synonym is so that "Dhall.Import.Types" can import a+    `Dhall.Import.Manager.Manager` type from "Dhall.Import.HTTP" that does the+    correct thing for both the GHC and GHCJS implementations+-}+type Manager = ()++defaultNewManager :: IO Manager+defaultNewManager = pure ()
src/Dhall.hs view
@@ -13,9 +13,11 @@ {-# LANGUAGE RecordWildCards            #-} {-# LANGUAGE ScopedTypeVariables        #-} {-# LANGUAGE TupleSections              #-}+{-# LANGUAGE TypeApplications           #-} {-# LANGUAGE TypeFamilies               #-} {-# LANGUAGE TypeOperators              #-} {-# LANGUAGE UndecidableInstances       #-}+{-# LANGUAGE ViewPatterns               #-}  {-| Please read the "Dhall.Tutorial" module, which contains a tutorial explaining     how to use the language, the compiler, and this library@@ -35,11 +37,12 @@     , startingContext     , substitutions     , normalizer+    , newManager     , defaultInputSettings     , InputSettings     , defaultEvaluateSettings     , EvaluateSettings-    , HasEvaluateSettings+    , HasEvaluateSettings(..)     , detailed      -- * Decoders@@ -72,6 +75,16 @@     , bool     , natural     , integer+    , word+    , word8+    , word16+    , word32+    , word64+    , int+    , int8+    , int16+    , int32+    , int64     , scientific     , double     , lazyText@@ -98,7 +111,7 @@     , union     , constructor     , GenericFromDhall(..)-+    , GenericFromDhallUnion(..)     , ToDhall(..)     , Inject     , inject@@ -121,6 +134,7 @@     , rawInput     , (>$<)     , (>*<)+    , Result      -- * Re-exports     , Natural@@ -154,13 +168,15 @@ import Data.Typeable                        (Proxy (..), Typeable) import Data.Vector                          (Vector) import Data.Void                            (Void)-import Data.Word                            (Word16, Word32, Word64, Word8)+import Data.Word                            (Word8, Word16, Word32, Word64)+import Data.Int                             (Int8, Int16, Int32, Int64) import Dhall.Import                         (Imported (..)) import Dhall.Parser                         (Src (..)) import Dhall.Syntax     ( Chunks (..)     , DhallDouble (..)     , Expr (..)+    , FunctionBinding (..)     , RecordField (..)     , Var (..)     )@@ -245,7 +261,7 @@     Failure e         -> fmap ExpectedTypeError e     Success expected' -> DhallErrors $ pure $ TypeMismatch $ InvalidDecoder expected' actual --- | Turn a `Text` message into an extraction failure+-- | Turn a `Data.Text.Text` message into an extraction failure extractError :: Text -> Extractor s a b extractError = Failure . DhallErrors . pure . ExtractError @@ -310,12 +326,17 @@  instance (Pretty s, Pretty a, Typeable s, Typeable a) => Exception (ExtractError s a) -{-| Every `Decoder` must obey the contract that if an expression's type matches the-    the `expected` type then the `extract` function must not fail with a type error.-    If not, then this value is returned.+{-| Every `Decoder` must obey the contract that if an expression's type matches+    the `expected` type then the `extract` function must not fail with a type+    error.  However, decoding may still fail for other reasons (such as the+    decoder for `Data.Map.Set`s rejecting a Dhall @List@ with duplicate+    elements). -    This value indicates that an invalid `Decoder` was provided to the `input`-    function+    This error type is used to indicate an internal error in the implementation+    of a `Decoder` where the expected type matched the Dhall expression, but the+    expression supplied to the extraction function did not match the expected+    type.  If this happens that means that the `Decoder` itself needs to be+    fixed. -} data InvalidDecoder s a = InvalidDecoder   { invalidDecoderExpected   :: Expr s a@@ -366,6 +387,7 @@   , _evaluateSettings = defaultEvaluateSettings   } + -- | Access the directory to resolve imports relative to. -- -- @since 1.16@@ -391,6 +413,7 @@   { _substitutions   :: Dhall.Substitution.Substitutions Src Void   , _startingContext :: Dhall.Context.Context (Expr Src Void)   , _normalizer      :: Maybe (Core.ReifiedNormalizer Void)+  , _newManager      :: IO Dhall.Import.Manager   }  -- | Default evaluation settings: no extra entries in the initial@@ -402,6 +425,7 @@   { _substitutions   = Dhall.Substitution.empty   , _startingContext = Dhall.Context.empty   , _normalizer      = Nothing+  , _newManager      = Dhall.Import.defaultNewManager   }  -- | Access the starting context used for evaluation and type-checking.@@ -440,6 +464,18 @@       => LensLike' f EvaluateSettings (Maybe (Core.ReifiedNormalizer Void))     l k s = fmap (\x -> s { _normalizer = x }) (k (_normalizer s)) +-- | Access the HTTP manager initializer.+--+-- @since 1.36+newManager+  :: (Functor f, HasEvaluateSettings s)+  => LensLike' f s (IO Dhall.Import.Manager)+newManager = evaluateSettings . l+  where+    l :: (Functor f)+      => LensLike' f EvaluateSettings (IO Dhall.Import.Manager)+    l k s = fmap (\x -> s { _newManager = x }) (k (_newManager s))+ -- | @since 1.16 class HasEvaluateSettings s where   evaluateSettings@@ -603,7 +639,7 @@             .  Lens.Family.set Dhall.Import.normalizer      _normalizer             .  Lens.Family.set Dhall.Import.startingContext _startingContext -    let status = transform (Dhall.Import.emptyStatus _rootDirectory)+    let status = transform (Dhall.Import.emptyStatusWithManager _newManager _rootDirectory)      expr' <- State.evalStateT (Dhall.Import.loadWith expr) status @@ -616,7 +652,7 @@ --   The intended use case is to allow easy extraction of Dhall values for --   making the function `Core.normalizeWith` easier to use. -----   For other use cases, use `input` from `Dhall` module. It will give you+--   For other use cases, use `input` from "Dhall" module. It will give you --   a much better user experience. rawInput     :: Alternative f@@ -771,7 +807,7 @@     }     deriving (Functor) -{-| Decode a `Bool`+{-| Decode a `Prelude.Bool`  >>> input bool "True" True@@ -784,7 +820,7 @@      expected = pure Bool -{-| Decode a `Natural`+{-| Decode a `Prelude.Natural`  >>> input natural "42" 42@@ -797,7 +833,7 @@      expected = pure Natural -{-| Decode an `Integer`+{-| Decode an `Prelude.Integer`  >>> input integer "+42" 42@@ -810,7 +846,114 @@      expected = pure Integer +wordHelper :: forall a . (Bounded a, Integral a) => Text -> Decoder a+wordHelper name = Decoder {..}+  where+    extract (NaturalLit n)+        | toInteger n <= toInteger (maxBound @a) =+            pure (fromIntegral n)+        | otherwise =+            extractError ("Decoded " <> name <> " is out of bounds: " <> Data.Text.pack (show n))+    extract expr =+        typeError expected expr++    expected = pure Natural++{-| Decode a `Word` from a Dhall @Natural@++>>> input word "42"+42+-}+word :: Decoder Word+word = wordHelper "Word"++{-| Decode a `Word8` from a Dhall @Natural@++>>> input word8 "42"+42+-}+word8 :: Decoder Word8+word8 = wordHelper "Word8"++{-| Decode a `Word16` from a Dhall @Natural@++>>> input word16 "42"+42+-}+word16 :: Decoder Word16+word16 = wordHelper "Word16"++{-| Decode a `Word32` from a Dhall @Natural@++>>> input word32 "42"+42+-}+word32 :: Decoder Word32+word32 = wordHelper "Word32"++{-| Decode a `Word64` from a Dhall @Natural@++>>> input word64 "42"+42+-}+word64 :: Decoder Word64+word64 = wordHelper "Word64"++intHelper :: forall a . (Bounded a, Integral a) => Text -> Decoder a+intHelper name = Decoder {..}+  where+    extract (IntegerLit n)+        | toInteger (minBound @a) <= n && n <= toInteger (maxBound @a) =+            pure (fromIntegral n)+        | otherwise =+            extractError ("Decoded " <> name <> " is out of bounds: " <> Data.Text.pack (show n))+    extract expr =+        typeError expected expr++    expected = pure Integer++{-| Decode an `Int` from a Dhall @Integer@++>>> input int "-42"+-42+-}+int :: Decoder Int+int = intHelper "Int"++{-| Decode an `Int8` from a Dhall @Integer@++>>> input int8 "-42"+-42+-}+int8 :: Decoder Int8+int8 = intHelper "Int8"++{-| Decode an `Int16` from a Dhall @Integer@++>>> input int16 "-42"+-42+-}+int16 :: Decoder Int16+int16 = intHelper "Int16"++{-| Decode an `Int32` from a Dhall @Integer@++>>> input int32 "-42"+-42+-}+int32 :: Decoder Int32+int32 = intHelper "Int32"++{-| Decode an `Int64` from a Dhall @Integer@++>>> input int64 "-42"+-42+-}+int64 :: Decoder Int64+int64 = intHelper "Int64"+ {-| Decode a `Scientific`+r  >>> input scientific "1e100" 1.0e100@@ -818,7 +961,7 @@ scientific :: Decoder Scientific scientific = fmap Data.Scientific.fromFloatDigits double -{-| Decode a `Double`+{-| Decode a `Prelude.Double`  >>> input double "42.0" 42.0@@ -831,7 +974,7 @@      expected = pure Double -{-| Decode lazy `Text`+{-| Decode lazy `Data.Text.Text`  >>> input lazyText "\"Test\"" "Test"@@ -839,7 +982,7 @@ lazyText :: Decoder Data.Text.Lazy.Text lazyText = fmap Data.Text.Lazy.fromStrict strictText -{-| Decode strict `Text`+{-| Decode strict `Data.Text.Text`  >>> input strictText "\"Test\"" "Test"@@ -933,7 +1076,7 @@      expectedOut = Pi "_" declared <$> expectedIn -{-| Decode a `Set` from a `List`+{-| Decode a `Data.Set.Set` from a `List`  >>> input (setIgnoringDuplicates natural) "[1, 2, 3]" fromList [1,2,3]@@ -947,7 +1090,7 @@ setIgnoringDuplicates :: (Ord a) => Decoder a -> Decoder (Data.Set.Set a) setIgnoringDuplicates = fmap Data.Set.fromList . list -{-| Decode a `HashSet` from a `List`+{-| Decode a `Data.HashSet.HashSet` from a `List`  >>> input (hashSetIgnoringDuplicates natural) "[1, 2, 3]" fromList [1,2,3]@@ -963,7 +1106,7 @@                           -> Decoder (Data.HashSet.HashSet a) hashSetIgnoringDuplicates = fmap Data.HashSet.fromList . list -{-| Decode a `Set` from a `List` with distinct elements+{-| Decode a `Data.Set.Set` from a `List` with distinct elements  >>> input (setFromDistinctList natural) "[1, 2, 3]" fromList [1,2,3]@@ -992,7 +1135,7 @@ setFromDistinctList :: (Ord a, Show a) => Decoder a -> Decoder (Data.Set.Set a) setFromDistinctList = setHelper Data.Set.size Data.Set.fromList -{-| Decode a `HashSet` from a `List` with distinct elements+{-| Decode a `Data.HashSet.HashSet` from a `List` with distinct elements  >>> input (hashSetFromDistinctList natural) "[1, 2, 3]" fromList [1,2,3]@@ -1201,9 +1344,39 @@ instance FromDhall Natural where     autoWith _ = natural +instance FromDhall Word where+    autoWith _ = word++instance FromDhall Word8 where+    autoWith _ = word8++instance FromDhall Word16 where+    autoWith _ = word16++instance FromDhall Word32 where+    autoWith _ = word32++instance FromDhall Word64 where+    autoWith _ = word64+ instance FromDhall Integer where     autoWith _ = integer +instance FromDhall Int where+    autoWith _ = int++instance FromDhall Int8 where+    autoWith _ = int8++instance FromDhall Int16 where+    autoWith _ = int16++instance FromDhall Int32 where+    autoWith _ = int32++instance FromDhall Int64 where+    autoWith _ = int64+ instance FromDhall Scientific where     autoWith _ = scientific @@ -1361,10 +1534,12 @@           where             die = typeError expected expr0 -            extract0 (Lam x _ expr) = extract1 (rename x "result" expr)+            extract0 (Lam (FunctionBinding { functionBindingVariable = x }) expr) =+                extract1 (rename x "result" expr)             extract0  _             = die -            extract1 (Lam y _ expr) = extract2 (rename y "Make" expr)+            extract1 (Lam (FunctionBinding { functionBindingVariable = y }) expr) =+                extract2 (rename y "Make" expr)             extract1  _             = die              extract2 expr = fmap resultToFix (Dhall.extract (autoWith inputNormalizer) expr)@@ -1496,9 +1671,9 @@     :: Text     -> Expr Src Void     -> (Text, Maybe (Expr Src Void))-unsafeExpectUnionLit _ (Field (Union _) k) =+unsafeExpectUnionLit _ (Field (Union _) (Core.fieldSelectionLabel -> k)) =     (k, Nothing)-unsafeExpectUnionLit _ (App (Field (Union _) k) v) =+unsafeExpectUnionLit _ (App (Field (Union _) (Core.fieldSelectionLabel -> k)) v) =     (k, Just v) unsafeExpectUnionLit name expression =     Core.internalError@@ -1523,13 +1698,16 @@     _                 -> Just e extractUnionConstructor     :: Expr s a -> Maybe (Text, Expr s a, Dhall.Map.Map Text (Maybe (Expr s a)))-extractUnionConstructor (App (Field (Union kts) fld) e) =+extractUnionConstructor (App (Field (Union kts) (Core.fieldSelectionLabel -> fld)) e) =   return (fld, e, Dhall.Map.delete fld kts)-extractUnionConstructor (Field (Union kts) fld) =+extractUnionConstructor (Field (Union kts) (Core.fieldSelectionLabel -> fld)) =   return (fld, RecordLit mempty, Dhall.Map.delete fld kts) extractUnionConstructor _ =   empty +{-| This is the underlying class that powers the `FromDhall` class's support+    for automatically deriving a generic implementation for a union type+-} class GenericFromDhallUnion t f where     genericUnionAutoWithNormalizer :: Proxy t -> InputNormalizer -> InterpretOptions -> UnionDecoder (f a) @@ -2130,16 +2308,16 @@         embed (L1 (M1 l)) =             case notEmptyRecordLit (embedL l) of                 Nothing ->-                    Field declared keyL+                    Field declared $ Core.makeFieldSelection keyL                 Just valL ->-                    App (Field declared keyL) valL+                    App (Field declared $ Core.makeFieldSelection keyL) valL          embed (R1 (M1 r)) =             case notEmptyRecordLit (embedR r) of                 Nothing ->-                    Field declared keyR+                    Field declared $ Core.makeFieldSelection keyR                 Just valR ->-                    App (Field declared keyR) valR+                    App (Field declared $ Core.makeFieldSelection keyR) valR          declared =             Union@@ -2166,15 +2344,15 @@       where         embed (L1 l) =             case maybeValL of-                Nothing   -> Field declared keyL-                Just valL -> App (Field declared keyL) valL+                Nothing   -> Field declared $ Core.makeFieldSelection keyL+                Just valL -> App (Field declared $ Core.makeFieldSelection keyL) valL           where             (keyL, maybeValL) =               unsafeExpectUnionLit "genericToDhallWithNormalizer (:+:)" (embedL l)         embed (R1 (M1 r)) =             case notEmptyRecordLit (embedR r) of-                Nothing   -> Field declared keyR-                Just valR -> App (Field declared keyR) valR+                Nothing   -> Field declared $ Core.makeFieldSelection keyR+                Just valR -> App (Field declared $ Core.makeFieldSelection keyR) valR          nR :: M1 i c h a         nR = undefined@@ -2193,12 +2371,12 @@       where         embed (L1 (M1 l)) =             case notEmptyRecordLit (embedL l) of-                Nothing   -> Field declared keyL-                Just valL -> App (Field declared keyL) valL+                Nothing   -> Field declared $ Core.makeFieldSelection keyL+                Just valL -> App (Field declared $ Core.makeFieldSelection keyL) valL         embed (R1 r) =             case maybeValR of-                Nothing   -> Field declared keyR-                Just valR -> App (Field declared keyR) valR+                Nothing   -> Field declared $ Core.makeFieldSelection keyR+                Just valR -> App (Field declared $ Core.makeFieldSelection keyR) valR           where             (keyR, maybeValR) =                 unsafeExpectUnionLit "genericToDhallWithNormalizer (:+:)" (embedR r)@@ -2220,15 +2398,15 @@       where         embed (L1 l) =             case maybeValL of-                Nothing   -> Field declared keyL-                Just valL -> App (Field declared keyL) valL+                Nothing   -> Field declared $ Core.makeFieldSelection keyL+                Just valL -> App (Field declared $ Core.makeFieldSelection keyL) valL           where             (keyL, maybeValL) =                 unsafeExpectUnionLit "genericToDhallWithNormalizer (:+:)" (embedL l)         embed (R1 r) =             case maybeValR of-                Nothing   -> Field declared keyR-                Just valR -> App (Field declared keyR) valR+                Nothing   -> Field declared $ Core.makeFieldSelection keyR+                Just valR -> App (Field declared $ Core.makeFieldSelection keyR) valR           where             (keyR, maybeValR) =                 unsafeExpectUnionLit "genericToDhallWithNormalizer (:+:)" (embedR r)@@ -2679,8 +2857,8 @@       { embed = \x ->           let (name, y) = embedF x           in  case notEmptyRecordLit y of-                  Nothing  -> Field (Union fields') name-                  Just val -> App (Field (Union fields') name) val+                  Nothing  -> Field (Union fields') $ Core.makeFieldSelection name+                  Just val -> App (Field (Union fields') $ Core.makeFieldSelection name) val       , declared =           Union fields'       }
src/Dhall/Binary.hs view
@@ -3,6 +3,7 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards   #-}+{-# LANGUAGE ViewPatterns      #-}  {-# OPTIONS_GHC -fno-warn-orphans #-} @@ -39,6 +40,7 @@     , Expr (..)     , File (..)     , FilePrefix (..)+    , FunctionBinding (..)     , Import (..)     , ImportHashed (..)     , ImportMode (..)@@ -66,6 +68,8 @@ import qualified Data.ByteString import qualified Data.ByteString.Lazy import qualified Data.ByteString.Short+import qualified Data.Foldable         as Foldable+import qualified Data.List.NonEmpty    as NonEmpty import qualified Data.Sequence import qualified Dhall.Crypto import qualified Dhall.Map@@ -93,7 +97,7 @@     -- ^ Version "1.0.0"     deriving (Enum, Bounded) --- | Render a `StandardVersion` as `Text`+-- | Render a `StandardVersion` as `Data.Text.Text` renderStandardVersion :: StandardVersion -> Text renderStandardVersion NoVersion = "none" renderStandardVersion V_1_0_0   = "1.0.0"@@ -256,7 +260,7 @@                                          b <- go -                                        return (Lam "_" _A b)+                                        return (Lam (Syntax.makeFunctionBinding "_" _A) b)                                      4 -> do                                         x <- Decoding.decodeString@@ -269,7 +273,7 @@                                          b <- go -                                        return (Lam x _A b)+                                        return (Lam (Syntax.makeFunctionBinding x _A) b)                                      _ ->                                         die ("Incorrect number of tokens used to encode a λ expression: " <> show len)@@ -391,7 +395,7 @@                                  x <- Decoding.decodeString -                                return (Field t x)+                                return (Field t (Syntax.makeFieldSelection x))                              10 -> do                                 t <- go@@ -579,6 +583,23 @@                                  return (ListLit (Just _T) empty) +                            29 -> do+                                l <- go++                                n <- Decoding.decodeListLen++                                ks₀ <- replicateDecoder n Decoding.decodeString++                                ks₁ <- case NonEmpty.nonEmpty ks₀ of+                                    Nothing ->+                                        die "0 field labels in decoded with expression"+                                    Just ks₁ ->+                                        return ks₁++                                r <- go++                                return (With l ks₁ r)+                             _ ->                                 die ("Unexpected tag: " <> show tag) @@ -706,13 +727,13 @@           where             (function, arguments) = unApply a -        Lam "_" _A b ->+        Lam (FunctionBinding { functionBindingVariable = "_", functionBindingAnnotation = _A }) b ->             encodeList3                 (Encoding.encodeInt 1)                 (go _A)                 (go b) -        Lam x _A b ->+        Lam (FunctionBinding { functionBindingVariable = x, functionBindingAnnotation = _A }) b ->             encodeList4                 (Encoding.encodeInt 1)                 (Encoding.encodeString x)@@ -819,7 +840,7 @@                 (Encoding.encodeInt 8)                 (encodeMapWith (go. recordFieldValue) xts) -        Field t x ->+        Field t (Syntax.fieldSelectionLabel -> x) ->             encodeList3                 (Encoding.encodeInt 9)                 (go t)@@ -939,8 +960,12 @@                 (go t)                 (go _T) -        a@With{} ->-            go (Syntax.desugarWith a)+        With l ks r ->+            encodeList4+                (Encoding.encodeInt 29)+                (go l)+                (encodeList (fmap Encoding.encodeString ks))+                (go r)          Note _ b ->             go b@@ -974,11 +999,12 @@ encodeList4 a b c d = Encoding.encodeListLen 4 <> a <> b <> c <> d {-# INLINE encodeList4 #-} -encodeListN :: Int -> [ Encoding ] -> Encoding-encodeListN len xs = Encoding.encodeListLen (fromIntegral len) <> mconcat xs+encodeListN :: Foldable f => Int -> f Encoding -> Encoding+encodeListN len xs =+    Encoding.encodeListLen (fromIntegral len) <> Foldable.fold xs {-# INLINE encodeListN #-} -encodeList :: [ Encoding ] -> Encoding+encodeList :: Foldable f => f Encoding -> Encoding encodeList xs = encodeListN (length xs) xs {-# INLINE encodeList #-} @@ -1179,7 +1205,7 @@ encodeExpression :: Serialise (Expr Void a) => Expr Void a -> ByteString encodeExpression = Serialise.serialise --- | Decode a Dhall expression from a CBOR `Term`+-- | Decode a Dhall expression from a CBOR `Codec.CBOR.Term.Term` decodeExpression     :: Serialise (Expr s a) => ByteString -> Either DecodingFailure (Expr s a) decodeExpression bytes =
src/Dhall/Context.hs view
@@ -15,8 +15,8 @@ import Data.Text (Text) import Prelude   hiding (lookup) -{-| A @(Context a)@ associates `Text` labels with values of type @a@.  Each-    `Text` label can correspond to multiple values of type @a@+{-| A @(Context a)@ associates `Data.Text.Text` labels with values of type @a@.+    Each `Data.Text.Text` label can correspond to multiple values of type @a@      The `Context` is used for type-checking when @(a = Expr X)@ 
src/Dhall/Core.hs view
@@ -27,6 +27,10 @@     , PreferAnnotation(..)     , RecordField(..)     , makeRecordField+    , FunctionBinding(..)+    , makeFunctionBinding+    , FieldSelection (..)+    , makeFieldSelection     , Expr(..)      -- * Normalization@@ -55,6 +59,7 @@     , chunkExprs     , bindingExprs     , recordFieldExprs+    , functionBindingExprs      -- * Let-blocks     , multiLet@@ -94,7 +99,7 @@ pretty = pretty_ {-# INLINE pretty #-} -{-| Escape a `Text` literal using Dhall's escaping rules+{-| Escape a `Data.Text.Text` literal using Dhall's escaping rules      Note that the result does not include surrounding quotes -}@@ -106,7 +111,7 @@ {-| Utility used to implement the @--censor@ flag, by:      * Replacing all `Src` text with spaces-    * Replacing all `Text` literals inside type errors with spaces+    * Replacing all `Dhall.Syntax.Text` literals inside type errors with spaces -} censorExpression :: Expr Src a -> Expr Src a censorExpression (TextLit chunks) = TextLit (censorChunks chunks)@@ -120,7 +125,9 @@      xys' = [ (censorText x, censorExpression y) | (x, y) <- xys ] --- | Utility used to censor `Text` by replacing all characters with a space+{-| Utility used to censor `Data.Text.Text` by replacing all characters with a+    space+-} censorText :: Text -> Text censorText = Data.Text.map (\_ -> ' ') 
src/Dhall/Deriving.hs view
@@ -58,7 +58,7 @@   , TrainCase      -- * Type-level versions of SingletonConstructors-  , ToSingletonConstructors+  , ToSingletonConstructors(..)   , Bare   , Wrapped   , Smart@@ -402,7 +402,7 @@  Second, we defined the @Name@ type in Haskell as a newtype over @Text@, with a @getName@ field for unwrapping. In Dhall, however, @Name@ is a synonym of-'Text', which is why 'input' above was expecting a record.+'Data.Text.Text', which is why 'Dhall.input' above was expecting a record. The 'Dhall.Bare' option for 'singletonConstructors' is a perfect fit here: it translates Haskell singleton constructors into the Dhall version of the nested type, without wrapping it into a record.
src/Dhall/Diff.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards   #-}+{-# LANGUAGE ViewPatterns      #-}  {-| This module provides functionality for concisely displaying the difference     between two expressions@@ -32,6 +33,7 @@     , Const (..)     , DhallDouble (..)     , Expr (..)+    , FunctionBinding (..)     , RecordField (..)     , Var (..)     )@@ -645,7 +647,9 @@ diff l@(Lam {}) r@(Lam {}) =     enclosed' "  " (rarrow <> " ") (docs l r)   where-    docs (Lam aL bL cL) (Lam aR bR cR) =+    docs+        (Lam (FunctionBinding { functionBindingVariable = aL, functionBindingAnnotation = bL }) cL)+        (Lam (FunctionBinding { functionBindingVariable = aR, functionBindingAnnotation = bR }) cR) =         Data.List.NonEmpty.cons (align doc) (docs cL cR)       where         doc =   lambda@@ -1061,7 +1065,7 @@ diffSelectorExpression l@(Field {}) r@(Field {}) =     enclosed' "  " (dot <> " ") (Data.List.NonEmpty.reverse (docs l r))   where-    docs (Field aL bL) (Field aR bR) =+    docs (Field aL (Syntax.fieldSelectionLabel -> bL)) (Field aR (Syntax.fieldSelectionLabel -> bR)) =         Data.List.NonEmpty.cons (diffLabel bL bR) (docs aL aR)     docs (Project aL (Left bL)) (Project aR (Left bR)) =         Data.List.NonEmpty.cons (diffLabels bL bR) (docs aL aR)@@ -1076,7 +1080,7 @@ diffSelectorExpression l@(Project {}) r@(Project {}) =     enclosed' "  " (dot <> " ") (Data.List.NonEmpty.reverse (docs l r))   where-    docs (Field aL bL) (Field aR bR) =+    docs (Field aL (Syntax.fieldSelectionLabel -> bL)) (Field aR (Syntax.fieldSelectionLabel ->bR)) =         Data.List.NonEmpty.cons (diffLabel bL bR) (docs aL aR)     docs (Project aL (Left bL)) (Project aR (Left bR)) =         Data.List.NonEmpty.cons (diffLabels bL bR) (docs aL aR)
src/Dhall/DirectoryTree.hs view
@@ -137,8 +137,8 @@         unexpectedExpression = expression  {- | This error indicates that you supplied an invalid Dhall expression to the-     `directoryTree` function.  The Dhall expression could not be translated to-     a directory tree.+     `toDirectoryTree` function.  The Dhall expression could not be translated+     to a directory tree. -} newtype FilesystemError =     FilesystemError { unexpectedExpression :: Expr Void Void }
src/Dhall/Eval.hs view
@@ -50,14 +50,14 @@   , textShow   ) where -import Data.Foldable  (foldr', toList)-import Data.Sequence  (Seq, ViewL (..), ViewR (..))-import Data.Text      (Text)-import Data.Void      (Void)-import Dhall.Map      (Map)-import Dhall.Set      (Set)-import GHC.Natural    (Natural)-import Prelude        hiding (succ)+import Data.Foldable (foldr', toList)+import Data.Sequence (Seq, ViewL (..), ViewR (..))+import Data.Text     (Text)+import Data.Void     (Void)+import Dhall.Map     (Map)+import Dhall.Set     (Set)+import GHC.Natural   (Natural)+import Prelude       hiding (succ)  import Dhall.Syntax     ( Binding (..)@@ -65,6 +65,7 @@     , Const (..)     , DhallDouble (..)     , Expr (..)+    , FunctionBinding (..)     , PreferAnnotation (..)     , RecordField (..)     , Var (..)@@ -389,7 +390,7 @@             VConst k         Var v ->             vVar env v-        Lam x a t ->+        Lam (FunctionBinding { functionBindingVariable = x, functionBindingAnnotation = a }) t ->             VLam (eval env a) (Closure x env t)         Pi x a b ->             VPi (eval env a) (Closure x env b)@@ -676,7 +677,10 @@         Prefer _ t u ->             vPrefer env (eval env t) (eval env u)         RecordCompletion t u ->-            eval env (Annot (Prefer PreferFromCompletion (Field t "default") u) (Field t "Type"))+            eval env (Annot (Prefer PreferFromCompletion (Field t def) u) (Field t typ))+          where+            def = Syntax.makeFieldSelection "default"+            typ = Syntax.makeFieldSelection "Type"         Merge x y ma ->             case (eval env x, eval env y, fmap (eval env) ma) of                 (VRecordLit m, VInject _ k mt, _)@@ -707,7 +711,7 @@                     in  VListLit Nothing s                 (x', ma') ->                     VToMap x' ma'-        Field t k ->+        Field t (Syntax.fieldSelectionLabel -> k) ->             vField (eval env t) k         Project t (Left ks) ->             vProjectByFields env (eval env t) (Dhall.Set.sort ks)@@ -984,10 +988,15 @@         VApp t u ->             quote env t `qApp` u         VLam a (freshClosure -> (x, v, t)) ->-            Lam x (quote env a) (quoteBind x (instantiate t v))+            Lam+                (Syntax.makeFunctionBinding x (quote env a))+                (quoteBind x (instantiate t v))         VHLam i t ->             case i of-                Typed (fresh -> (x, v)) a -> Lam x (quote env a) (quoteBind x (t v))+                Typed (fresh -> (x, v)) a ->+                    Lam+                        (Syntax.makeFunctionBinding x (quote env a))+                        (quoteBind x (t v))                 Prim                      -> quote env (t VPrimVar)                 NaturalSubtractZero       -> App NaturalSubtract (NaturalLit 0) @@ -1102,7 +1111,7 @@         VToMap t ma ->             ToMap (quote env t) (fmap (quote env) ma)         VField t k ->-            Field (quote env t) k+            Field (quote env t) $ Syntax.makeFieldSelection k         VProject t p ->             Project (quote env t) (fmap (quote env) p)         VAssert t ->@@ -1110,9 +1119,9 @@         VEquivalent t u ->             Equivalent (quote env t) (quote env u)         VInject m k Nothing ->-            Field (Union (fmap (fmap (quote env)) m)) k+            Field (Union (fmap (fmap (quote env)) m)) $ Syntax.makeFieldSelection k         VInject m k (Just t) ->-            Field (Union (fmap (fmap (quote env)) m)) k `qApp` t+            Field (Union (fmap (fmap (quote env)) m)) (Syntax.makeFieldSelection k) `qApp` t         VEmbed a ->             Embed a         VPrimVar ->@@ -1165,8 +1174,8 @@                 Const k             Var (V x i) ->                 goVar e0 x i-            Lam x t u ->-                Lam "_" (go t) (goBind x u)+            Lam (FunctionBinding src0 x src1 src2 t) u ->+                Lam (FunctionBinding src0 "_" src1 src2 (go t)) (goBind x u)             Pi x a b ->                 Pi "_" (go a) (goBind x b)             App t u ->@@ -1303,4 +1312,4 @@         go                     = goEnv e0         goBind x               = goEnv (Bind e0 x)         goChunks (Chunks ts x) = Chunks (fmap (fmap go) ts) x-        goRecordField (RecordField s0 e) = RecordField s0 (go e)+        goRecordField (RecordField s0 e s1 s2) = RecordField s0 (go e) s1 s2
src/Dhall/Freeze.hs view
@@ -8,9 +8,13 @@ module Dhall.Freeze     ( -- * Freeze       freeze+    , freezeWithManager     , freezeExpression+    , freezeExpressionWithManager     , freezeImport+    , freezeImportWithManager     , freezeRemoteImport+    , freezeRemoteImportWithManager        -- * Types     , Scope(..)@@ -57,7 +61,15 @@     -- ^ Current working directory     -> Import     -> IO Import-freezeImport directory import_ = do+freezeImport = freezeImportWithManager Dhall.Import.defaultNewManager++-- | See 'freezeImport'.+freezeImportWithManager+    :: IO Dhall.Import.Manager+    -> FilePath+    -> Import+    -> IO Import+freezeImportWithManager newManager directory import_ = do     let unprotectedImport =             import_                 { importHashed =@@ -66,7 +78,7 @@                         }                 } -    let status = Dhall.Import.emptyStatus directory+    let status = Dhall.Import.emptyStatusWithManager newManager directory      expression <- State.evalStateT (Dhall.Import.loadWith (Embed unprotectedImport)) status @@ -93,9 +105,17 @@     -- ^ Current working directory     -> Import     -> IO Import-freezeRemoteImport directory import_ =+freezeRemoteImport = freezeRemoteImportWithManager Dhall.Import.defaultNewManager++-- | See 'freezeRemoteImport'.+freezeRemoteImportWithManager+    :: IO Dhall.Import.Manager+    -> FilePath+    -> Import+    -> IO Import+freezeRemoteImportWithManager newManager directory import_ =     case importType (importHashed import_) of-        Remote {} -> freezeImport directory import_+        Remote {} -> freezeImportWithManager newManager directory import_         _         -> return import_  -- | Specifies which imports to freeze@@ -125,7 +145,19 @@     -> CharacterSet     -> Censor     -> IO ()-freeze outputMode input0 scope intent characterSet censor = go input0+freeze = freezeWithManager Dhall.Import.defaultNewManager++-- | See 'freeze'.+freezeWithManager+    :: IO Dhall.Import.Manager+    -> OutputMode+    -> PossiblyTransitiveInput+    -> Scope+    -> Intent+    -> CharacterSet+    -> Censor+    -> IO ()+freezeWithManager newManager outputMode input0 scope intent characterSet censor = go input0   where     go input = do         let directory = case input of@@ -134,7 +166,7 @@                 PossiblyTransitiveInputFile file _ ->                     System.FilePath.takeDirectory file -        let status = Dhall.Import.emptyStatus directory+        let status = Dhall.Import.emptyStatusWithManager newManager directory          (originalText, transitivity) <- case input of             PossiblyTransitiveInputFile file transitivity -> do@@ -160,7 +192,7 @@             NonTransitive ->                 return () -        frozenExpression <- freezeExpression directory scope intent parsedExpression+        frozenExpression <- freezeExpressionWithManager newManager directory scope intent parsedExpression          let doc =  Pretty.pretty header                 <> Dhall.Pretty.prettyCharacterSet characterSet frozenExpression@@ -213,13 +245,23 @@     -> Intent     -> Expr s Import     -> IO (Expr s Import)-freezeExpression directory scope intent expression = do+freezeExpression = freezeExpressionWithManager Dhall.Import.defaultNewManager++-- | See 'freezeExpression'.+freezeExpressionWithManager+    :: IO Dhall.Import.Manager+    -> FilePath+    -> Scope+    -> Intent+    -> Expr s Import+    -> IO (Expr s Import)+freezeExpressionWithManager newManager directory scope intent expression = do     let freezeScope =             case scope of-                AllImports        -> freezeImport-                OnlyRemoteImports -> freezeRemoteImport+                AllImports        -> freezeImportWithManager+                OnlyRemoteImports -> freezeRemoteImportWithManager -    let freezeFunction = freezeScope directory+    let freezeFunction = freezeScope newManager directory      let cache             -- This case is necessary because `transformOf` is a bottom-up
src/Dhall/Import.hs view
@@ -6,6 +6,8 @@ {-# LANGUAGE RankNTypes          #-} {-# LANGUAGE RecordWildCards     #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE ViewPatterns        #-}+ {-# OPTIONS_GHC -Wall #-}  {-| Dhall lets you import external expressions located either in local files or@@ -101,7 +103,9 @@ module Dhall.Import (     -- * Import       load+    , loadWithManager     , loadRelativeTo+    , loadRelativeToWithManager     , loadWith     , localToPath     , hashExpression@@ -109,6 +113,8 @@     , writeExpressionToSemanticCache     , warnAboutMissingCaches     , assertNoImports+    , Manager+    , defaultNewManager     , Status(..)     , SemanticCacheMode(..)     , Chained@@ -116,6 +122,7 @@     , chainedFromLocalHere     , chainedChangeMode     , emptyStatus+    , emptyStatusWithManager     , stack     , cache     , Depends(..)@@ -128,6 +135,7 @@     , chainImport     , dependencyToFile     , ImportSemantics+    , HTTPHeader     , Cycle(..)     , ReferentiallyOpaque(..)     , Imported(..)@@ -170,9 +178,9 @@     , ImportHashed (..)     , ImportMode (..)     , ImportType (..)-    , RecordField (..)     , URL (..)     , bindingExprs+    , functionBindingExprs     , recordFieldExprs     ) @@ -343,6 +351,7 @@ throwMissingImport :: (MonadCatch m, Exception e) => e -> m a throwMissingImport e = throwM (MissingImports [toException e]) +-- | HTTP headers type HTTPHeader = (CI ByteString, ByteString)  -- | Exception thrown when a HTTP url is imported but dhall was built without@@ -496,9 +505,9 @@     return (Chained (canonicalize (parent <> child)))  -- | Load an import, resulting in a fully resolved, type-checked and normalised---   expression. @loadImport@ handles the 'hot' cache in @Status@ and defers to---   `loadImportWithSemanticCache` for imports that aren't in the @Status@ cache---   already.+--   expression. @loadImport@ handles the \"hot\" cache in @Status@ and defers+--   to @loadImportWithSemanticCache@ for imports that aren't in the @Status@+--   cache already. loadImport :: Chained -> StateT Status IO ImportSemantics loadImport import_ = do     Status {..} <- State.get@@ -511,7 +520,7 @@             return importSemantics  -- | Load an import from the 'semantic cache'. Defers to---   `loadImportWithSemisemanticCache` for imports that aren't frozen (and+--   @loadImportWithSemisemanticCache@ for imports that aren't frozen (and --   therefore not cached semantically), as well as those that aren't cached yet. loadImportWithSemanticCache :: Chained -> StateT Status IO ImportSemantics loadImportWithSemanticCache@@ -688,15 +697,15 @@      -- importSemantics is alpha-beta-normal by construction!     let importSemantics = case importType of-            Missing -> Field locationType "Missing"+            Missing -> Field locationType $ Core.makeFieldSelection  "Missing"             local@(Local _ _) ->-                App (Field locationType "Local")+                App (Field locationType $ Core.makeFieldSelection "Local")                   (TextLit (Chunks [] (Core.pretty local)))             remote_@(Remote _) ->-                App (Field locationType "Remote")+                App (Field locationType $ Core.makeFieldSelection "Remote")                   (TextLit (Chunks [] (Core.pretty remote_)))             Env env ->-                App (Field locationType "Environment")+                App (Field locationType $ Core.makeFieldSelection "Environment")                   (TextLit (Chunks [] (Core.pretty env)))      return (ImportSemantics {..})@@ -778,7 +787,7 @@  toHeader :: Expr s a -> Maybe HTTPHeader toHeader (RecordLit m) = do-    (RecordField _ (TextLit (Chunks [] keyText)), RecordField _ (TextLit (Chunks [] valueText)))+    (Core.recordFieldValue -> TextLit (Chunks [] keyText), Core.recordFieldValue -> TextLit (Chunks [] valueText))         <- lookupHeader <|> lookupMapKey     let keyBytes   = Data.Text.Encoding.encodeUtf8 keyText     let valueBytes = Data.Text.Encoding.encodeUtf8 valueText@@ -1012,8 +1021,12 @@  -- | Default starting `Status`, importing relative to the given directory. emptyStatus :: FilePath -> Status-emptyStatus = emptyStatusWith fetchRemote+emptyStatus = emptyStatusWithManager defaultNewManager +-- | See 'emptyStatus'.+emptyStatusWithManager :: IO Manager -> FilePath -> Status+emptyStatusWithManager newManager = emptyStatusWith newManager fetchRemote+ {-| Generalized version of `load`      You can configure the desired behavior through the initial `Status` that you@@ -1074,12 +1087,18 @@   Let a b              -> Let <$> bindingExprs loadWith a <*> loadWith b   Record m             -> Record <$> traverse (recordFieldExprs loadWith) m   RecordLit m          -> RecordLit <$> traverse (recordFieldExprs loadWith) m+  Lam a b              -> Lam <$> functionBindingExprs loadWith a <*> loadWith b+  Field a b            -> Field <$> loadWith a <*> pure b   expression           -> Syntax.unsafeSubExpressions loadWith expression  -- | Resolve all imports within an expression load :: Expr Src Import -> IO (Expr Src Void)-load = loadRelativeTo "." UseSemanticCache+load = loadWithManager defaultNewManager +-- | See 'load'.+loadWithManager :: IO Manager -> Expr Src Import -> IO (Expr Src Void)+loadWithManager newManager = loadRelativeToWithManager newManager "." UseSemanticCache+ printWarning :: (MonadIO m) => String -> m () printWarning message = do     let warning =@@ -1092,10 +1111,19 @@ -- | Resolve all imports within an expression, importing relative to the given -- directory. loadRelativeTo :: FilePath -> SemanticCacheMode -> Expr Src Import -> IO (Expr Src Void)-loadRelativeTo rootDirectory semanticCacheMode expression =+loadRelativeTo = loadRelativeToWithManager defaultNewManager++-- | See 'loadRelativeTo'.+loadRelativeToWithManager+    :: IO Manager+    -> FilePath+    -> SemanticCacheMode+    -> Expr Src Import+    -> IO (Expr Src Void)+loadRelativeToWithManager newManager rootDirectory semanticCacheMode expression =     State.evalStateT         (loadWith expression)-        (emptyStatus rootDirectory) { _semanticCacheMode = semanticCacheMode }+        (emptyStatusWithManager newManager rootDirectory) { _semanticCacheMode = semanticCacheMode }  encodeExpression     :: StandardVersion
src/Dhall/Import/Types.hs view
@@ -31,7 +31,7 @@ import System.FilePath                  (isRelative, splitDirectories)  #ifdef WITH_HTTP-import Dhall.Import.Manager (Manager)+import qualified Dhall.Import.Manager #endif  import qualified Data.Text@@ -39,8 +39,8 @@ import qualified Dhall.Map          as Map import qualified Dhall.Substitution --- | A fully 'chained' import, i.e. if it contains a relative path that path is---   relative to the current directory. If it is a remote import with headers+-- | A fully \"chained\" import, i.e. if it contains a relative path that path+--   is relative to the current directory. If it is a remote import with headers --   those are well-typed (either of type `List { header : Text, value Text}` or --   `List { mapKey : Text, mapValue Text})` and in normal form. These --   invariants are preserved by the API exposed by @Dhall.Import@.@@ -67,6 +67,24 @@ -} data SemanticCacheMode = IgnoreSemanticCache | UseSemanticCache deriving (Eq) +-- | Shared state for HTTP requests+type Manager =+#ifdef WITH_HTTP+    Dhall.Import.Manager.Manager+#else+    ()+#endif++-- | The default HTTP 'Manager'+defaultNewManager :: IO Manager+defaultNewManager =+#ifdef WITH_HTTP+  Dhall.Import.Manager.defaultNewManager+#else+  pure ()+#endif++ -- | State threaded throughout the import process data Status = Status     { _stack :: NonEmpty Chained@@ -81,12 +99,10 @@     -- ^ Cache of imported expressions with their node id in order to avoid     --   importing the same expression twice with different values -#ifdef WITH_HTTP+    , _newManager :: IO Manager     , _manager :: Maybe Manager-#else-    , _manager :: Maybe Void-#endif-    -- ^ Used to cache the `Manager` when making multiple requests+    -- ^ Used to cache the `Dhall.Import.Manager.Manager` when making multiple+    -- requests      , _remote :: URL -> StateT Status IO Data.Text.Text     -- ^ The remote resolver, fetches the content at the given URL.@@ -100,10 +116,10 @@     , _semanticCacheMode :: SemanticCacheMode     } --- | Initial `Status`, parameterised over the remote resolver, importing---   relative to the given directory.-emptyStatusWith :: (URL -> StateT Status IO Data.Text.Text) -> FilePath -> Status-emptyStatusWith _remote rootDirectory = Status {..}+-- | Initial `Status`, parameterised over the HTTP 'Manager' and the remote resolver,+--   importing relative to the given directory.+emptyStatusWith :: IO Manager -> (URL -> StateT Status IO Data.Text.Text) -> FilePath -> Status+emptyStatusWith _newManager _remote rootDirectory = Status {..}   where     _stack = pure (Chained rootImport) @@ -171,11 +187,9 @@  {-| This exception indicates that there was an internal error in Dhall's     import-related logic-    the `expected` type then the `extract` function must succeed.  If not, then-    this exception is thrown -    This exception indicates that an invalid `Type` was provided to the `input`-    function+    This exception indicates that an invalid `Dhall.Syntax.Type` was provided to+    the `Dhall.input` function -} data InternalError = InternalError deriving (Typeable) @@ -202,11 +216,12 @@  instance Exception InternalError --- | Wrapper around `HttpException`s with a prettier `Show` instance.+-- | Wrapper around `Network.HTTP.Client.HttpException`s with a prettier `Show`+-- instance -- -- In order to keep the library API constant even when the @with-http@ Cabal -- flag is disabled the pretty error message is pre-rendered and the real--- 'HttpExcepion' is stored in a 'Dynamic'+-- 'Network.HTTP.Client.HttpException' is stored in a 'Dynamic' data PrettyHttpException = PrettyHttpException String Dynamic     deriving (Typeable) 
src/Dhall/Lint.hs view
@@ -68,7 +68,7 @@         Just (Core.shift (-1) (V a 0) d) removeUnusedBindings _ = Nothing --- | Fix `Let` bindings  that the user probably meant to be `assert`s+-- | Fix `Let` bindings  that the user probably meant to be @assert@s fixAssert :: Expr s a -> Maybe (Expr s a) fixAssert (Let (Binding { value = v@(Core.shallowDenote -> Equivalent {}), ..}) body) =     Just (Let (Binding { value = Assert v, .. }) body)
src/Dhall/Main.hs view
@@ -12,6 +12,7 @@     ( -- * Options       Options(..)     , Mode(..)+    , ResolveMode(..)     , parseOptions     , parserInfoOptions @@ -161,15 +162,19 @@           }     | Encode { file :: Input, json :: Bool }     | Decode { file :: Input, json :: Bool, quiet :: Bool }-    | Text { file :: Input }+    | Text { file :: Input, output :: Output }     | DirectoryTree { file :: Input, path :: FilePath }     | Schemas { file :: Input, outputMode :: OutputMode, schemas :: Text }     | SyntaxTree { file :: Input, noted :: Bool } +-- | This specifies how to resolve transitive dependencies data ResolveMode     = Dot+    -- ^ Generate a DOT file for @graphviz@     | ListTransitiveDependencies+    -- ^ List all transitive dependencies as text, one per line     | ListImmediateDependencies+    -- ^ List immediate dependencies as text, one per line  -- | Groups of subcommands data Group@@ -250,7 +255,7 @@             Generate             "text"             "Render a Dhall expression that evaluates to a Text literal"-            (Text <$> parseFile)+            (Text <$> parseFile <*> parseOutput)     <|> subcommand             Generate             "to-directory-tree"@@ -902,7 +907,10 @@              case normalizedExpression of                 Dhall.Core.TextLit (Dhall.Core.Chunks [] text) ->-                    Data.Text.IO.putStr text+                    let write = case output of+                          StandardOutput -> Data.Text.IO.putStr+                          OutputFile file_ -> Data.Text.IO.writeFile file_+                    in write text                 _ -> do                     let invalidDecoderExpected :: Expr Void Void                         invalidDecoderExpected = Dhall.Core.Text
src/Dhall/Map.hs view
@@ -356,7 +356,7 @@     ks' = filterKeys (\k -> Data.Map.member k m') ks {-# INLINABLE filter #-} -{-| Restrict a 'Map' to only those keys found in a @"Data.Set".'Set'@.+{-| Restrict a 'Map' to only those keys found in a @"Data.Set".'Data.Set.Set'@.  >>> restrictKeys (fromList [("A",1),("B",2)]) (Data.Set.fromList ["A"]) fromList [("A",1)]@@ -369,7 +369,7 @@     ks' = filterKeys (\k -> Data.Set.member k s) ks {-# INLINABLE restrictKeys #-} -{-| Remove all keys in a @"Data.Set".'Set'@ from a 'Map'+{-| Remove all keys in a @"Data.Set".'Data.Set.Set'@ from a 'Map'  >>> withoutKeys (fromList [("A",1),("B",2)]) (Data.Set.fromList ["A"]) fromList [("B",2)]@@ -679,7 +679,7 @@ elems (Map m (Original ks)) = fmap (\k -> m Data.Map.! k) ks {-# INLINABLE elems #-} -{-| Return the @"Data.Set".'Set'@ of the keys+{-| Return the @"Data.Set".'Data.Set.Set'@ of the keys  >>> keysSet (fromList [("B",1),("A",2)]) fromList ["A","B"]
src/Dhall/Normalize.hs view
@@ -1,6 +1,8 @@ {-# LANGUAGE BangPatterns      #-}+{-# LANGUAGE LambdaCase        #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RankNTypes        #-}+{-# LANGUAGE ViewPatterns      #-}  module Dhall.Normalize (       alphaNormalize@@ -12,7 +14,7 @@     , ReifiedNormalizer (..)     , judgmentallyEqual     , subst-    , shift+    , Syntax.shift     , isNormalized     , isNormalizedWith     , freeIn@@ -31,6 +33,8 @@     , Chunks (..)     , DhallDouble (..)     , Expr (..)+    , FieldSelection (..)+    , FunctionBinding (..)     , PreferAnnotation (..)     , RecordField (..)     , Var (..)@@ -55,115 +59,28 @@ judgmentallyEqual = Eval.judgmentallyEqual {-# INLINE judgmentallyEqual #-} -{-| `shift` is used by both normalization and type-checking to avoid variable-    capture by shifting variable indices--    For example, suppose that you were to normalize the following expression:--> λ(a : Type) → λ(x : a) → (λ(y : a) → λ(x : a) → y) x--    If you were to substitute @y@ with @x@ without shifting any variable-    indices, then you would get the following incorrect result:--> λ(a : Type) → λ(x : a) → λ(x : a) → x  -- Incorrect normalized form--    In order to substitute @x@ in place of @y@ we need to `shift` @x@ by @1@ in-    order to avoid being misinterpreted as the @x@ bound by the innermost-    lambda.  If we perform that `shift` then we get the correct result:--> λ(a : Type) → λ(x : a) → λ(x : a) → x@1--    As a more worked example, suppose that you were to normalize the following-    expression:-->     λ(a : Type)-> →   λ(f : a → a → a)-> →   λ(x : a)-> →   λ(x : a)-> →   (λ(x : a) → f x x@1) x@1--    The correct normalized result would be:-->     λ(a : Type)-> →   λ(f : a → a → a)-> →   λ(x : a)-> →   λ(x : a)-> →   f x@1 x--    The above example illustrates how we need to both increase and decrease-    variable indices as part of substitution:--    * We need to increase the index of the outer @x\@1@ to @x\@2@ before we-      substitute it into the body of the innermost lambda expression in order-      to avoid variable capture.  This substitution changes the body of the-      lambda expression to @(f x\@2 x\@1)@--    * We then remove the innermost lambda and therefore decrease the indices of-      both @x@s in @(f x\@2 x\@1)@ to @(f x\@1 x)@ in order to reflect that one-      less @x@ variable is now bound within that scope--    Formally, @(shift d (V x n) e)@ modifies the expression @e@ by adding @d@ to-    the indices of all variables named @x@ whose indices are greater than-    @(n + m)@, where @m@ is the number of bound variables of the same name-    within that scope--    In practice, @d@ is always @1@ or @-1@ because we either:--    * increment variables by @1@ to avoid variable capture during substitution-    * decrement variables by @1@ when deleting lambdas after substitution--    @n@ starts off at @0@ when substitution begins and increments every time we-    descend into a lambda or let expression that binds a variable of the same-    name in order to avoid shifting the bound variables by mistake.--}-shift :: Int -> Var -> Expr s a -> Expr s a-shift d (V x n) (Var (V x' n')) = Var (V x' n'')-  where-    n'' = if x == x' && n <= n' then n' + d else n'-shift d (V x n) (Lam x' _A b) = Lam x' _A' b'-  where-    _A' = shift d (V x n ) _A-    b'  = shift d (V x n') b-      where-        n' = if x == x' then n + 1 else n-shift d (V x n) (Pi x' _A _B) = Pi x' _A' _B'-  where-    _A' = shift d (V x n ) _A-    _B' = shift d (V x n') _B-      where-        n' = if x == x' then n + 1 else n-shift d (V x n) (Let (Binding src0 f src1 mt src2 r) e) =-    Let (Binding src0 f src1 mt' src2 r') e'-  where-    e' = shift d (V x n') e-      where-        n' = if x == f then n + 1 else n--    mt' = fmap (fmap (shift d (V x n))) mt-    r'  =             shift d (V x n)  r-shift d v expression = Lens.over Syntax.subExpressions (shift d v) expression- {-| Substitute all occurrences of a variable with an expression  > subst x C B  ~  B[x := C] -} subst :: Var -> Expr s a -> Expr s a -> Expr s a subst _ _ (Const a) = Const a-subst (V x n) e (Lam y _A b) = Lam y _A' b'+subst (V x n) e (Lam (FunctionBinding src0 y src1 src2 _A) b) =+    Lam (FunctionBinding src0 y src1 src2 _A') b'   where-    _A' = subst (V x n )                  e  _A-    b'  = subst (V x n') (shift 1 (V y 0) e)  b+    _A' = subst (V x n )                         e  _A+    b'  = subst (V x n') (Syntax.shift 1 (V y 0) e)  b     n'  = if x == y then n + 1 else n subst (V x n) e (Pi y _A _B) = Pi y _A' _B'   where-    _A' = subst (V x n )                  e  _A-    _B' = subst (V x n') (shift 1 (V y 0) e) _B+    _A' = subst (V x n )                         e  _A+    _B' = subst (V x n') (Syntax.shift 1 (V y 0) e) _B     n'  = if x == y then n + 1 else n subst v e (Var v') = if v == v' then e else Var v' subst (V x n) e (Let (Binding src0 f src1 mt src2 r) b) =     Let (Binding src0 f src1 mt' src2 r') b'   where-    b' = subst (V x n') (shift 1 (V f 0) e) b+    b' = subst (V x n') (Syntax.shift 1 (V f 0) e) b       where         n' = if x == f then n + 1 else n @@ -196,8 +113,9 @@ {-| α-normalize an expression by renaming all bound variables to @\"_\"@ and     using De Bruijn indices to distinguish them ->>> alphaNormalize (Lam "a" (Const Type) (Lam "b" (Const Type) (Lam "x" "a" (Lam "y" "b" "x"))))-Lam "_" (Const Type) (Lam "_" (Const Type) (Lam "_" (Var (V "_" 1)) (Lam "_" (Var (V "_" 1)) (Var (V "_" 1)))))+>>> mfb = Syntax.makeFunctionBinding+>>> alphaNormalize (Lam (mfb "a" (Const Type)) (Lam (mfb "b" (Const Type)) (Lam (mfb "x" "a") (Lam (mfb "y" "b") "x"))))+Lam (FunctionBinding {functionBindingSrc0 = Nothing, functionBindingVariable = "_", functionBindingSrc1 = Nothing, functionBindingSrc2 = Nothing, functionBindingAnnotation = Const Type}) (Lam (FunctionBinding {functionBindingSrc0 = Nothing, functionBindingVariable = "_", functionBindingSrc1 = Nothing, functionBindingSrc2 = Nothing, functionBindingAnnotation = Const Type}) (Lam (FunctionBinding {functionBindingSrc0 = Nothing, functionBindingVariable = "_", functionBindingSrc1 = Nothing, functionBindingSrc2 = Nothing, functionBindingAnnotation = Var (V "_" 1)}) (Lam (FunctionBinding {functionBindingSrc0 = Nothing, functionBindingVariable = "_", functionBindingSrc1 = Nothing, functionBindingSrc2 = Nothing, functionBindingAnnotation = Var (V "_" 1)}) (Var (V "_" 1)))))      α-normalization does not affect free variables: @@ -225,7 +143,7 @@ {-| Reduce an expression to its normal form, performing beta reduction and applying     any custom definitions. -    `normalizeWith` is designed to be used with function `typeWith`. The `typeWith`+    `normalizeWith` is designed to be used with function `Dhall.TypeCheck.typeWith`. The `Dhall.TypeCheck.typeWith`     function allows typing of Dhall functions in a custom typing context whereas     `normalizeWith` allows evaluating Dhall expressions in a custom context. @@ -253,10 +171,11 @@     :: (Monad m, Eq a) => NormalizerM m a -> Expr s a -> m (Expr t a) normalizeWithM ctx e0 = loop (Syntax.denote e0)  where- loop e =  case e of+ loop =  \case     Const k -> pure (Const k)     Var v -> pure (Var v)-    Lam x _A b -> Lam x <$> _A' <*> b'+    Lam (FunctionBinding { functionBindingVariable = x, functionBindingAnnotation = _A }) b ->+        Lam <$> (Syntax.makeFunctionBinding x <$> _A') <*> b'       where         _A' = loop _A         b'  = loop b@@ -272,11 +191,11 @@               f' <- loop f               a' <- loop a               case f' of-                Lam x _A b₀ -> do+                Lam (FunctionBinding _ x _ _ _A) b₀ -> do -                    let a₂ = shift 1 (V x 0) a'+                    let a₂ = Syntax.shift 1 (V x 0) a'                     let b₁ = subst (V x 0) a₂ b₀-                    let b₂ = shift (-1) (V x 0) b₁+                    let b₂ = Syntax.shift (-1) (V x 0) b₁                      loop b₂                 _ ->@@ -299,7 +218,7 @@                         lazyLoop !n = App succ' (lazyLoop (n - 1))                     App NaturalBuild g -> loop (App (App (App g Natural) succ) zero)                       where-                        succ = Lam "n" Natural (NaturalPlus "n" (NaturalLit 1))+                        succ = Lam (Syntax.makeFunctionBinding "n" Natural) (NaturalPlus "n" (NaturalLit 1))                          zero = NaturalLit 0                     App NaturalIsZero (NaturalLit n) -> pure (BoolLit (n == 0))@@ -336,14 +255,14 @@                         pure (TextLit (Chunks [] (Data.Text.pack (show n))))                     App (App ListBuild _A₀) g -> loop (App (App (App g list) cons) nil)                       where-                        _A₁ = shift 1 "a" _A₀+                        _A₁ = Syntax.shift 1 "a" _A₀                          list = App List _A₀                          cons =-                            Lam "a" _A₀-                                (Lam "as"-                                    (App List _A₁)+                            Lam (Syntax.makeFunctionBinding "a" _A₀)+                                (Lam+                                    (Syntax.makeFunctionBinding "as" (App List _A₁))                                     (ListAppend (ListLit Nothing (pure "a")) "as")                                 ) @@ -405,9 +324,9 @@                             Just app' -> loop app'     Let (Binding _ f _ _ _ r) b -> loop b''       where-        r'  = shift   1  (V f 0) r+        r'  = Syntax.shift   1  (V f 0) r         b'  = subst (V f 0) r' b-        b'' = shift (-1) (V f 0) b'+        b'' = Syntax.shift (-1) (V f 0) b'     Annot x _ -> loop x     Bool -> pure Bool     BoolLit b -> pure (BoolLit b)@@ -528,11 +447,11 @@     None -> pure None     Record kts -> Record . Dhall.Map.sort <$> kts'       where-        f (RecordField s0 expr) = RecordField s0 <$> loop expr+        f (RecordField s0 expr s1 s2) = (\e -> RecordField s0 e s1 s2) <$> loop expr         kts' = traverse f kts     RecordLit kvs -> RecordLit . Dhall.Map.sort <$> kvs'       where-        f (RecordField s0 expr) = RecordField s0 <$> loop expr+        f (RecordField s0 expr s1 s2) = (\e -> RecordField s0 e s1 s2) <$> loop expr         kvs' = traverse f kvs     Union kts -> Union . Dhall.Map.sort <$> kts'       where@@ -546,7 +465,7 @@         decide (RecordLit m) (RecordLit n) =             RecordLit (Dhall.Map.unionWith f m n)           where-            f (RecordField _ expr) (RecordField _ expr') =+            f (RecordField _ expr _ _) (RecordField _ expr' _ _) =               Syntax.makeRecordField $ decide expr expr'         decide l r =             Combine mk l r@@ -559,7 +478,7 @@         decide (Record m) (Record n) =             Record (Dhall.Map.unionWith f m n)           where-            f (RecordField _ expr) (RecordField _ expr') =+            f (RecordField _ expr _ _) (RecordField _ expr' _ _) =               Syntax.makeRecordField $ decide expr expr'         decide l r =             CombineTypes l r@@ -576,14 +495,17 @@         decide l r =             Prefer PreferFromSource l r     RecordCompletion x y ->-        loop (Annot (Prefer PreferFromCompletion (Field x "default") y) (Field x "Type"))+        loop (Annot (Prefer PreferFromCompletion (Field x def) y) (Field x typ))+      where+        def = Syntax.makeFieldSelection "default"+        typ = Syntax.makeFieldSelection "Type"     Merge x y t      -> do         x' <- loop x         y' <- loop y         case x' of             RecordLit kvsX ->                 case y' of-                    Field (Union ktsY) kY ->+                    Field (Union ktsY) (Syntax.fieldSelectionLabel -> kY) ->                         case Dhall.Map.lookup kY ktsY of                             Just Nothing ->                                 case recordFieldValue <$> Dhall.Map.lookup kY kvsX of@@ -591,7 +513,7 @@                                     Nothing -> Merge x' y' <$> t'                             _ ->                                 Merge x' y' <$> t'-                    App (Field (Union ktsY) kY) vY ->+                    App (Field (Union ktsY) (Syntax.fieldSelectionLabel -> kY)) vY ->                         case Dhall.Map.lookup kY ktsY of                             Just (Just _) ->                                 case recordFieldValue <$> Dhall.Map.lookup kY kvsX of@@ -635,7 +557,7 @@                 return (ListLit listType keyValues)             _ ->                 return (ToMap x' t')-    Field r x        -> do+    Field r k@FieldSelection{fieldSelectionLabel = x}        -> do         let singletonRecordLit v = RecordLit (Dhall.Map.singleton x v)          r' <- loop r@@ -643,21 +565,21 @@             RecordLit kvs ->                 case Dhall.Map.lookup x kvs of                     Just v  -> pure $ recordFieldValue v-                    Nothing -> Field <$> (RecordLit <$> traverse (Syntax.recordFieldExprs loop) kvs) <*> pure x-            Project r_ _ -> loop (Field r_ x)+                    Nothing -> Field <$> (RecordLit <$> traverse (Syntax.recordFieldExprs loop) kvs) <*> pure k+            Project r_ _ -> loop (Field r_ k)             Prefer _ (RecordLit kvs) r_ -> case Dhall.Map.lookup x kvs of-                Just v -> pure (Field (Prefer PreferFromSource (singletonRecordLit v) r_) x)-                Nothing -> loop (Field r_ x)+                Just v -> pure (Field (Prefer PreferFromSource (singletonRecordLit v) r_) k)+                Nothing -> loop (Field r_ k)             Prefer _ l (RecordLit kvs) -> case Dhall.Map.lookup x kvs of                 Just v -> pure $ recordFieldValue v-                Nothing -> loop (Field l x)+                Nothing -> loop (Field l k)             Combine m (RecordLit kvs) r_ -> case Dhall.Map.lookup x kvs of-                Just v -> pure (Field (Combine m (singletonRecordLit v) r_) x)-                Nothing -> loop (Field r_ x)+                Just v -> pure (Field (Combine m (singletonRecordLit v) r_) k)+                Nothing -> loop (Field r_ k)             Combine m l (RecordLit kvs) -> case Dhall.Map.lookup x kvs of-                Just v -> pure (Field (Combine m l (singletonRecordLit v)) x)-                Nothing -> loop (Field l x)-            _ -> pure (Field r' x)+                Just v -> pure (Field (Combine m l (singletonRecordLit v)) k)+                Nothing -> loop (Field l k)+            _ -> pure (Field r' k)     Project x (Left fields)-> do         x' <- loop x         let fieldsSet = Dhall.Set.toSet fields@@ -732,10 +654,11 @@     loop e = case e of       Const _ -> True       Var _ -> True-      Lam _ a b -> loop a && loop b+      Lam (FunctionBinding Nothing _ Nothing Nothing a) b -> loop a && loop b+      Lam _ _ -> False       Pi _ a b -> loop a && loop b       App f a -> loop f && loop a && case App f a of-          App (Lam _ _ _) _ -> False+          App (Lam _ _) _ -> False           App (App (App (App NaturalFold (NaturalLit _)) _) _) _ -> False           App NaturalBuild _ -> False           App NaturalIsZero (NaturalLit _) -> False@@ -852,8 +775,14 @@       Optional -> True       Some a -> loop a       None -> True-      Record kts -> Dhall.Map.isSorted kts && all (loop . recordFieldValue) kts-      RecordLit kvs -> Dhall.Map.isSorted kvs && all (loop . recordFieldValue) kvs+      Record kts -> Dhall.Map.isSorted kts && all decide kts+        where+          decide (RecordField Nothing exp' Nothing Nothing) = loop exp'+          decide _ = False+      RecordLit kvs -> Dhall.Map.isSorted kvs && all decide kvs+        where+          decide (RecordField Nothing exp' Nothing Nothing) = loop exp'+          decide _ = False       Union kts -> Dhall.Map.isSorted kts && all (all loop) kts       Combine _ x y -> loop x && loop y && decide x y         where@@ -885,7 +814,7 @@       ToMap x t -> case x of           RecordLit _ -> False           _ -> loop x && all loop t-      Field r k -> case r of+      Field r (FieldSelection Nothing k Nothing) -> case r of           RecordLit _ -> False           Project _ _ -> False           Prefer _ (RecordLit m) _ -> Dhall.Map.keys m == [k] && loop r@@ -893,6 +822,7 @@           Combine _ (RecordLit m) _ -> Dhall.Map.keys m == [k] && loop r           Combine _ _ (RecordLit m) -> Dhall.Map.keys m == [k] && loop r           _ -> loop r+      Field _ _ -> False       Project r p -> loop r &&           case p of               Left s -> case r of@@ -916,7 +846,7 @@ True >>> "x" `freeIn` "y" False->>> "x" `freeIn` Lam "x" (Const Type) "x"+>>> "x" `freeIn` Lam (Syntax.makeFunctionBinding "x" (Const Type)) "x" False -} freeIn :: Eq a => Var -> Expr s a -> Bool
src/Dhall/Parser.hs view
@@ -76,7 +76,7 @@  instance Exception ParseError --- | Parse an expression from `Text` containing a Dhall program+-- | Parse an expression from `Data.Text.Text` containing a Dhall program exprFromText   :: String -- ^ User-friendly name describing the input expression,             --   used in parsing error messages
src/Dhall/Parser/Combinators.hs view
@@ -63,7 +63,7 @@         <>  Pretty.renderString                 (Dhall.Pretty.layout (pretty source)) --- | Doesn't force the 'Text' part+-- | Doesn't force the 'Data.Text.Text' part laxSrcEq :: Src -> Src -> Bool laxSrcEq (Src p q _) (Src p' q' _) = eq p p' && eq q q'   where
src/Dhall/Parser/Expression.hs view
@@ -18,6 +18,7 @@ import Text.Parser.Combinators (choice, try, (<?>))  import qualified Control.Monad+import qualified Control.Monad.Combinators          as Combinators import qualified Control.Monad.Combinators.NonEmpty as Combinators.NonEmpty import qualified Data.ByteArray.Encoding import qualified Data.ByteString@@ -33,13 +34,6 @@ import Dhall.Parser.Combinators import Dhall.Parser.Token --- | Get the current source position-getSourcePos :: Text.Megaparsec.MonadParsec e s m =>-                m Text.Megaparsec.SourcePos-getSourcePos =-    Text.Megaparsec.getSourcePos-{-# INLINE getSourcePos #-}- -- | Get the current source offset (in tokens) getOffset :: Text.Megaparsec.MonadParsec e s m => m Int getOffset = Text.Megaparsec.stateOffset <$> Text.Megaparsec.getParserState@@ -57,17 +51,17 @@ -} src :: Parser a -> Parser Src src parser = do-    before      <- getSourcePos+    before      <- Text.Megaparsec.getSourcePos     (tokens, _) <- Text.Megaparsec.match parser-    after       <- getSourcePos+    after       <- Text.Megaparsec.getSourcePos     return (Src before after tokens)  -- | Same as `src`, except also return the parsed value srcAnd :: Parser a -> Parser (Src, a) srcAnd parser = do-    before      <- getSourcePos+    before      <- Text.Megaparsec.getSourcePos     (tokens, x) <- Text.Megaparsec.match parser-    after       <- getSourcePos+    after       <- Text.Megaparsec.getSourcePos     return (Src before after tokens, x)  {-| Wrap a `Parser` to still match the same text, but to wrap the resulting@@ -75,9 +69,9 @@ -} noted :: Parser (Expr Src a) -> Parser (Expr Src a) noted parser = do-    before      <- getSourcePos+    before      <- Text.Megaparsec.getSourcePos     (tokens, e) <- Text.Megaparsec.match parser-    after       <- getSourcePos+    after       <- Text.Megaparsec.getSourcePos     let src₀ = Src before after tokens     case e of         Note src₁ _ | laxSrcEq src₀ src₁ -> return e@@ -137,11 +131,11 @@             _lambda             whitespace             _openParens-            whitespace+            src0 <- src whitespace             a <- label-            whitespace+            src1 <- src whitespace             _colon-            nonemptyWhitespace+            src2 <- src nonemptyWhitespace             b <- expression             whitespace             _closeParens@@ -149,7 +143,7 @@             _arrow             whitespace             c <- expression-            return (Lam a b c)+            return (Lam (FunctionBinding (Just src0) a (Just src1) (Just src2) b) c)          alternative1 = do             try (_if *> nonemptyWhitespace)@@ -443,18 +437,29 @@     selectorExpression = noted (do             a <- primitiveExpression -            let recordType = _openParens *> whitespace *> expression <* whitespace <* _closeParens+            let recordType = whitespace *> _openParens *> whitespace *> expression <* whitespace <* _closeParens              let field               x  e = Field   e  x             let projectBySet        xs e = Project e (Left  xs)             let projectByExpression xs e = Project e (Right xs) +            let fieldSelection = do+                    src0 <- src whitespace+                    l <- anyLabel+                    pos <- Text.Megaparsec.getSourcePos++                    -- FIXME: Suffix whitespace can't be parsed given our limitation+                    -- about whitespace treatment, but for @dhall-docs@ this+                    -- is enough+                    let src1 = Src pos pos ""+                    return (FieldSelection (Just src0) l (Just src1))+             let alternatives =-                        fmap field               anyLabel-                    <|> fmap projectBySet        labels+                        fmap field               fieldSelection+                    <|> fmap projectBySet        (whitespace *> labels)                     <|> fmap projectByExpression recordType -            b <- Text.Megaparsec.many (try (whitespace *> _dot *> whitespace *> alternatives))+            b <- Text.Megaparsec.many (try (whitespace *> _dot *> alternatives))             return (foldl' (\e k -> k e) a b) )      primitiveExpression =@@ -786,12 +791,15 @@      nonEmptyRecordTypeOrLiteral firstSrc0 = do             let nonEmptyRecordType = do-                    a <- try (anyLabelOrSome <* whitespace <* _colon)-                    nonemptyWhitespace+                    (firstKeySrc1, a) <- try $ do+                        a <- anyLabelOrSome+                        s <- src whitespace+                        _colon+                        return (s, a) -                    b <- expression+                    firstKeySrc2 <- src nonemptyWhitespace -                    whitespace+                    b <- expression                      e <- Text.Megaparsec.many $ do                         (src0', c) <- try $ do@@ -800,48 +808,60 @@                             c <- anyLabelOrSome                             return (src0', c) -                        whitespace+                        src1 <- src whitespace                          _colon -                        nonemptyWhitespace+                        src2 <- src nonemptyWhitespace                          d <- expression                          whitespace -                        return (c, RecordField (Just src0') d)+                        return (c, RecordField (Just src0') d (Just src1) (Just src2))                      _ <- optional (whitespace *> _comma)                     whitespace -                    m <- toMap ((a, RecordField (Just firstSrc0) b) : e)+                    m <- toMap ((a, RecordField (Just firstSrc0) b (Just firstKeySrc1) (Just firstKeySrc2)) : e)                      return (Record m)              let keysValue maybeSrc = do-                    src0 <- case maybeSrc of+                    firstSrc0' <- case maybeSrc of                         Just src0 -> return src0                         Nothing -> src whitespace-                    keys <- Combinators.NonEmpty.sepBy1 anyLabelOrSome (try (whitespace *> _dot) *> whitespace)+                    firstLabel <- anyLabelOrSome+                    firstSrc1 <- src whitespace +                    let parseLabelWithWhsp = try $ do+                            _dot+                            src0 <- src whitespace+                            l <- anyLabelOrSome+                            src1 <- src whitespace+                            return (src0, l, src1)++                    restKeys <- Combinators.many parseLabelWithWhsp+                    let keys = (firstSrc0', firstLabel, firstSrc1) :| restKeys+                     let normalRecordEntry = do-                            try (whitespace *> _equal)+                            try _equal -                            whitespace+                            lastSrc2 <- src whitespace                              value <- expression -                            let cons key (key', values@(RecordField s0 _)) =-                                    (key, RecordField s0 $ RecordLit [ (key', values) ])+                            let cons (s0, key, s1) (key', values) =+                                    (key, RecordField (Just s0) (RecordLit [ (key', values) ]) (Just s1) Nothing) -                            let nil = (NonEmpty.last keys, RecordField (Just src0) value)+                            let (lastSrc0, lastLabel, lastSrc1) = NonEmpty.last keys+                            let nil = (lastLabel, RecordField (Just lastSrc0) value (Just lastSrc1) (Just lastSrc2))                              return (foldr cons nil (NonEmpty.init keys))                      let punnedEntry =                             case keys of-                                x :| [] -> return (x, RecordField (Just src0) $ Var (V x 0))+                                (s0, x, s1) :| [] -> return (x, RecordField (Just s0) (Var (V x 0)) (Just s1) Nothing)                                 _       -> empty                      (normalRecordEntry <|> punnedEntry) <* whitespace
src/Dhall/Parser/Token.hs view
@@ -185,7 +185,7 @@     let negative = fmap (\_ -> negate) (char '-')     positive <|> negative ) <?> "sign" -{-| Parse a `Double` literal+{-| Parse a `Dhall.Syntax.Double` literal      This corresponds to the @double-literal@ rule from the official grammar -}@@ -257,7 +257,7 @@     a <- text "Infinity" >> return (1.0/0.0)     return (sign a) ) <?> "literal" -{-| Parse an `Integer` literal+{-| Parse an `Dhall.Syntax.Integer` literal      This corresponds to the @integer-literal@ rule from the official grammar -}@@ -267,7 +267,7 @@     a    <- naturalLiteral     return (sign (fromIntegral a)) ) <?> "literal" -{-| Parse a `Natural` literal +{-| Parse a `Dhall.Syntax.Natural` literal       This corresponds to the @natural-literal@ rule from the official grammar -}@@ -552,7 +552,7 @@     ||  ('\x23' <= c && c <= '\x2E')     ||  ('\x30' <= c && c <= '\x10FFFF') -{-| The `pathComponent` function uses this type to distinguish whether to parse+{-| The @pathComponent@ function uses this type to distinguish whether to parse     a URL path component or a file path component -} data ComponentType = URLComponent | FileComponent
src/Dhall/Pretty/Internal.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE LambdaCase        #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards   #-}+{-# LANGUAGE ViewPatterns      #-}  {-# OPTIONS_GHC -Wall #-} @@ -16,6 +17,7 @@      , CharacterSet(..)     , prettyCharacterSet+    , prettyImportExpression      , prettyVar     , pretty_@@ -77,6 +79,7 @@ import qualified Data.HashSet import qualified Data.List import qualified Data.List.NonEmpty                        as NonEmpty+import qualified Data.Maybe import qualified Data.Set import qualified Data.Text                                 as Text import qualified Data.Text.Prettyprint.Doc                 as Pretty@@ -157,18 +160,29 @@     -> Doc Ann renderSrc strip (Just (Src {..}))     | not (Text.all isWhitespace srcText) =-        Pretty.align (Pretty.concatWith f newLines <> suffix)+        renderComment (strip srcText)+renderSrc _ _ =+    mempty++{-| Render a comment.++    Any preprocessing, such as whitespace stripping, needs to be handled by the+    caller, see e.g. 'renderSrc'.++    See the documentation for 'renderSrc' for examples.+-}+renderComment :: Text -> Doc Ann+renderComment text =+    Pretty.align (Pretty.concatWith f newLines <> suffix)   where     horizontalSpace c = c == ' ' || c == '\t' -    strippedText = strip srcText-     suffix =-        if Text.null strippedText || Text.last strippedText == '\n'+        if Text.null text || Text.last text == '\n'         then mempty         else " " -    oldLines = Text.splitOn "\n" strippedText+    oldLines = Text.splitOn "\n" text      spacePrefix = Text.takeWhile horizontalSpace @@ -197,9 +211,27 @@                 in  Pretty.pretty l0 : map perLine ls      f x y = x <> Pretty.hardline <> y-renderSrc _ _ =-    mempty +{-| This is a variant of 'renderSrc' with the following differences:++      * The 'srcText' is stripped of all whitespace at the start and the end.+      * When the stripped 'srcText' is empty, the result is 'Nothing'.+-}+renderSrcMaybe :: Maybe Src -> Maybe (Doc Ann)+renderSrcMaybe (Just Src{..}) =+    case Text.dropAround isWhitespace srcText of+        "" -> Nothing+        t  -> Just (renderComment t)+renderSrcMaybe _ = Nothing++{-| @+    'containsComment' mSrc ≡ 'Data.Maybe.isJust' ('renderSrcMaybe' mSrc)+    @+-}+containsComment :: Maybe Src -> Bool+containsComment Nothing        = False+containsComment (Just Src{..}) = not (Text.all isWhitespace srcText)+ -- Annotation helpers keyword, syntax, label, literal, builtin, operator :: Doc Ann -> Doc Ann keyword  = Pretty.annotate Keyword@@ -452,10 +484,31 @@ prettyAnyLabel :: Text -> Doc Ann prettyAnyLabel = prettyLabelShared True -prettyAnyLabels :: Foldable list => list Text -> Doc Ann-prettyAnyLabels =-    mconcat . Pretty.punctuate dot . fmap prettyAnyLabel . toList+prettyAnyLabels :: Foldable list => list (Maybe Src, Text, Maybe Src) -> Doc Ann+prettyAnyLabels keys = Pretty.group (Pretty.flatAlt long short)+  where+    short = (mconcat . Pretty.punctuate dot . map prettyKey . toList) keys +    long =+        case map prettyKey (toList keys) of+            []       -> mempty+            [doc]    -> doc+            doc:docs ->+                  Pretty.align+                . mconcat+                . Pretty.punctuate (Pretty.hardline <> ". ")+                $ Pretty.indent 2 doc : docs++    prettyKey (mSrc0, key, mSrc1) =+          Pretty.align+        . mconcat+        . Pretty.punctuate Pretty.hardline+        . Data.Maybe.catMaybes+        $ [ renderSrcMaybe mSrc0+          , Just (prettyAnyLabel key)+          , renderSrcMaybe mSrc1+          ]+ prettyLabels :: Set Text -> Doc Ann prettyLabels a     | Data.Set.null (Dhall.Set.toSet a) =@@ -530,13 +583,33 @@ This means the structure of parsed let-blocks is preserved. -} prettyCharacterSet :: Pretty a => CharacterSet -> Expr Src a -> Doc Ann-prettyCharacterSet characterSet expression =-    Pretty.group (prettyExpression expression)+prettyCharacterSet characterSet = prettyCompleteExpression   where-    prettyExpression a0@(Lam _ _ _) =+    PrettyPrinters{..} = prettyPrinters characterSet++-- Mainly used by the `Pretty` instance for `Import`+prettyImportExpression :: Pretty a => Expr Src a -> Doc Ann+prettyImportExpression = prettyImportExpression_+  where+    PrettyPrinters{..} = prettyPrinters Unicode++data PrettyPrinters a = PrettyPrinters+    { prettyCompleteExpression :: Expr Src a -> Doc Ann+    , prettyImportExpression_  :: Expr Src a -> Doc Ann+    }++prettyPrinters :: Pretty a => CharacterSet -> PrettyPrinters a+prettyPrinters characterSet =+    PrettyPrinters{..}+  where+    prettyCompleteExpression expression =+        Pretty.group (prettyExpression expression)++    prettyExpression a0@(Lam _ _) =         arrows characterSet (docs a0)       where-        docs (Lam a b c) = Pretty.group (Pretty.flatAlt long short) : docs c+        docs (Lam (FunctionBinding { functionBindingVariable = a, functionBindingAnnotation = b }) c) =+            Pretty.group (Pretty.flatAlt long short) : docs c           where             long =  (lambda characterSet <> space)                 <>  Pretty.align@@ -703,7 +776,7 @@             <>  Pretty.align (keyword "with" <> " " <> update)          (update, _) =-            prettyKeyValue prettyAnyLabels prettyOperatorExpression equals (b, c)+            prettyKeyValue prettyOperatorExpression equals (makeKeyValue b c)     prettyExpression (Assert a) =         Pretty.group (Pretty.flatAlt long short)       where@@ -730,18 +803,18 @@             Pretty.align                 (   keyword "merge"                 <>  Pretty.hardline-                <>  Pretty.indent 2 (prettyImportExpression a)+                <>  Pretty.indent 2 (prettyImportExpression_ a)                 <>  Pretty.hardline-                <>  Pretty.indent 2 (prettyImportExpression b)+                <>  Pretty.indent 2 (prettyImportExpression_ b)                 <>  Pretty.hardline                 <>  colon <> space                 <>  prettyApplicationExpression c                 )          short = keyword "merge" <> space-            <>  prettyImportExpression a+            <>  prettyImportExpression_ a             <>  " "-            <>  prettyImportExpression b+            <>  prettyImportExpression_ b             <>  space <> colon <> space             <>  prettyApplicationExpression c     prettyAnnotatedExpression (ToMap a (Just b)) =@@ -751,14 +824,14 @@             Pretty.align                 (   keyword "toMap"                 <>  Pretty.hardline-                <>  Pretty.indent 2 (prettyImportExpression a)+                <>  Pretty.indent 2 (prettyImportExpression_ a)                 <>  Pretty.hardline                 <>  colon <> space                 <>  prettyApplicationExpression b                 )          short = keyword "toMap" <> space-            <>  prettyImportExpression a+            <>  prettyImportExpression_ a             <>  space <> colon <> space             <>  prettyApplicationExpression b     prettyAnnotatedExpression a0@(Annot _ _) =@@ -1076,27 +1149,27 @@             e | Note _ b <- e ->                   go args b               | null args ->-                  prettyImportExpression e -- just a performance optimization+                  prettyImportExpression_ e -- just a performance optimization               | Just doc <- preserveSource e ->                   app doc args               | otherwise ->-                  app (prettyImportExpression e) args+                  app (prettyImportExpression_ e) args          app f args =             enclose'                 "" "" " " ""                 ( duplicate f-                : map (fmap (Pretty.indent 2) . duplicate . prettyImportExpression) args+                : map (fmap (Pretty.indent 2) . duplicate . prettyImportExpression_) args                 ) -    prettyImportExpression :: Pretty a => Expr Src a -> Doc Ann-    prettyImportExpression (Embed a) =+    prettyImportExpression_ :: Pretty a => Expr Src a -> Doc Ann+    prettyImportExpression_ (Embed a) =         Pretty.pretty a-    prettyImportExpression a+    prettyImportExpression_ a         | Just doc <- preserveSource a =             doc         | Note _ b <- a =-            prettyImportExpression b+            prettyImportExpression_ b         | otherwise =             prettyCompletionExpression a @@ -1107,7 +1180,7 @@                 Pretty.align                     (   prettySelectorExpression a                     <>  doubleColon-                    <>  prettyCompletionLit 0 (recordFieldValue <$> kvs)+                    <>  prettyCompletionLit 0 kvs                     )             _ ->    prettySelectorExpression a                 <>  doubleColon@@ -1121,7 +1194,7 @@             prettySelectorExpression a      prettySelectorExpression :: Pretty a => Expr Src a -> Doc Ann-    prettySelectorExpression (Field a b) =+    prettySelectorExpression (Field a (Dhall.Syntax.fieldSelectionLabel -> b)) =         prettySelectorExpression a <> dot <> prettyAnyLabel b     prettySelectorExpression (Project a (Left b)) =         prettySelectorExpression a <> dot <> prettyLabels b@@ -1216,9 +1289,9 @@     prettyPrimitiveExpression (TextLit a) =         prettyChunks a     prettyPrimitiveExpression (Record a) =-        prettyRecord $ recordFieldValue <$> a+        prettyRecord a     prettyPrimitiveExpression (RecordLit a) =-        prettyRecordLit $ recordFieldValue <$> a+        prettyRecordLit a     prettyPrimitiveExpression (Union a) =         prettyUnion a     prettyPrimitiveExpression (ListLit Nothing b) =@@ -1239,115 +1312,141 @@      prettyKeyValue         :: Pretty a-        => (k -> Doc Ann)-        -> (Expr Src a -> Doc Ann)+        => (Expr Src a -> Doc Ann)         -> Doc Ann-        -> (k, Expr Src a)+        -> KeyValue Src a         -> (Doc Ann, Doc Ann)-    prettyKeyValue prettyKey prettyValue separator (key, val) =+    prettyKeyValue prettyValue separator (KeyValue key mSrc val) =         duplicate (Pretty.group (Pretty.flatAlt long short))       where         completion _T r =-                " "-            <>  prettySelectorExpression _T+                prettySelectorExpression _T             <>  doubleColon             <>  case shallowDenote r of                     RecordLit kvs ->-                        prettyCompletionLit 2 $ recordFieldValue <$> kvs+                        prettyCompletionLit 2 kvs                     _ ->                         prettySelectorExpression r -        short = prettyKey key+        short = prettyAnyLabels key             <>  " "             <>  separator             <>  " "+            <>  case renderSrcMaybe mSrc of+                    Nothing  -> mempty+                    Just doc -> doc <> Pretty.hardline             <>  prettyValue val -        long =-                prettyKey key-            <>  " "+        long =  Pretty.align+                    (   prettyAnyLabels key+                    <>  preSeparator+                    )             <>  separator-            <>  case shallowDenote val of-                    Some val' ->-                            " " <> builtin "Some"-                        <>  case shallowDenote val' of-                                RecordCompletion _T r ->-                                    completion _T r+            <>  case renderSrcMaybe mSrc of+                    Just doc ->+                            preComment+                        <>  Pretty.align+                                (   doc+                                <>  Pretty.hardline+                                <>  prettyValue val+                                )+                    Nothing ->+                        case shallowDenote val of+                            Some val' ->+                                    " "+                                <>  builtin "Some"+                                <>  case shallowDenote val' of+                                        RecordCompletion _T r ->+                                                " "+                                            <>  completion _T r -                                RecordLit _ ->-                                        Pretty.hardline-                                    <>  "  "-                                    <>  prettyImportExpression val'+                                        RecordLit _ ->+                                                Pretty.hardline+                                            <>  "  "+                                            <>  prettyImportExpression_ val' -                                ListLit _ xs-                                    | not (null xs) ->-                                            Pretty.hardline-                                        <>  "  "-                                        <>  prettyImportExpression val'+                                        ListLit _ xs+                                            | not (null xs) ->+                                                    Pretty.hardline+                                                <>  "  "+                                                <>  prettyImportExpression_ val' -                                _ ->    Pretty.hardline-                                    <>  "    "-                                    <>  prettyImportExpression val'+                                        _ ->    Pretty.hardline+                                            <>  "    "+                                            <>  prettyImportExpression_ val' -                    ToMap val' Nothing ->-                            " " <> keyword "toMap"-                        <>  case shallowDenote val' of-                                RecordCompletion _T r ->-                                    completion _T r-                                _ ->    Pretty.hardline-                                    <>  "    "-                                    <>  prettyImportExpression val'+                            ToMap val' Nothing ->+                                    " "+                                <>  keyword "toMap"+                                <>  case shallowDenote val' of+                                        RecordCompletion _T r ->+                                            completion _T r+                                        _ ->    Pretty.hardline+                                            <>  "    "+                                            <>  prettyImportExpression_ val' -                    RecordCompletion _T r ->-                        completion _T r+                            RecordCompletion _T r ->+                                " " <> completion _T r -                    RecordLit _ ->-                            Pretty.hardline-                        <>  "  "-                        <>  prettyValue val+                            RecordLit _ ->+                                    Pretty.hardline+                                <>  "  "+                                <>  prettyValue val -                    ListLit _ xs-                        | not (null xs) ->-                                Pretty.hardline-                            <>  "  "-                            <>  prettyValue val+                            ListLit _ xs+                                | not (null xs) ->+                                        Pretty.hardline+                                    <>  "  "+                                    <>  prettyValue val -                    _ -> -                            Pretty.hardline-                        <>  "    "-                        <>  prettyValue val+                            _ ->+                                Pretty.group+                                    (   Pretty.flatAlt (Pretty.hardline <> "    ") " "+                                    <>  prettyValue val+                                    )+          where+            (preSeparator, preComment) =+                case key of+                    (_, _, mSrc2) :| [] | not (containsComment mSrc2) ->+                        (" ", Pretty.hardline <> "    ")+                    _ ->+                        (Pretty.hardline, " ") -    prettyRecord :: Pretty a => Map Text (Expr Src a) -> Doc Ann++    prettyRecord :: Pretty a => Map Text (RecordField Src a) -> Doc Ann     prettyRecord =           braces-        . map (prettyKeyValue prettyAnyLabel prettyExpression colon)+        . map (prettyKeyValue prettyExpression colon . adapt)         . Map.toList+      where+        adapt (key, RecordField mSrc0 val mSrc1 mSrc2) = KeyValue (pure (mSrc0, key, mSrc1)) mSrc2 val -    prettyRecordLit :: Pretty a => Map Text (Expr Src a) -> Doc Ann+    prettyRecordLit :: Pretty a => Map Text (RecordField Src a) -> Doc Ann     prettyRecordLit = prettyRecordLike braces -    prettyCompletionLit :: Pretty a => Int -> Map Text (Expr Src a) -> Doc Ann+    prettyCompletionLit :: Pretty a => Int -> Map Text (RecordField Src a) -> Doc Ann     prettyCompletionLit = prettyRecordLike . hangingBraces      prettyRecordLike braceStyle a         | Data.Foldable.null a =             lbrace <> equals <> rbrace         | otherwise =-            braceStyle (map prettyRecordEntry (Map.toList consolidated))+            braceStyle (map prettyRecordEntry consolidated)       where         consolidated = consolidateRecordLiteral a -        prettyRecordEntry (keys, value) =+        prettyRecordEntry kv@(KeyValue keys mSrc2 val) =             case keys of-                key :| []-                    | Var (V key' 0) <- Dhall.Syntax.shallowDenote value-                    , key == key' ->-                        duplicate (prettyAnyLabel key)+                (mSrc0, key, mSrc1) :| []+                    | Var (V key' 0) <- Dhall.Syntax.shallowDenote val+                    , key == key'+                    , not (containsComment mSrc2) ->+                        duplicate (prettyAnyLabels [(mSrc0, key, mSrc1)])                 _ ->-                    prettyKeyValue prettyAnyLabels prettyExpression equals (keys, value)+                    prettyKeyValue prettyExpression equals kv      prettyAlternative (key, Just val) =-        prettyKeyValue prettyAnyLabel prettyExpression colon (key, val)+        prettyKeyValue prettyExpression colon (makeKeyValue (pure key) val)     prettyAlternative (key, Nothing) =         duplicate (prettyAnyLabel key) @@ -1479,7 +1578,8 @@      toChunk (t0, t1) = (t0, TextLit (Chunks [] t1)) --- | Split `Text` on a predicate, preserving all parts of the original string.+-- | Split `Data.Text.Text` on a predicate, preserving all parts of the original+-- string. -- -- >>> splitOnPredicate (== 'x') "" -- ([],"")@@ -1513,27 +1613,35 @@ pretty_ :: Pretty a => a -> Text pretty_ = prettyToStrictText +data KeyValue s a = KeyValue+    { _keyValueKeys  :: NonEmpty (Maybe s, Text, Maybe s)+    , _keyValueSrc   :: Maybe s+    , _keyValueValue :: Expr s a+    }++makeKeyValue :: NonEmpty Text -> Expr s a -> KeyValue s a+makeKeyValue keys expr = KeyValue (adapt <$> keys) Nothing expr+  where+    adapt key = (Nothing, key, Nothing)+ {- This utility function converts-   `{ x = { y = { z = 1 } } }` to `{ x.y.z. = 1 }`+   `{ x = { y = { z = 1 } } }` to `{ x.y.z = 1 }` -} consolidateRecordLiteral-    :: Map Text (Expr s a) -> Map (NonEmpty Text) (Expr s a)-consolidateRecordLiteral = Map.fromList . fmap adapt . Map.toList+    :: Map Text (RecordField Src a) -> [KeyValue Src a]+consolidateRecordLiteral = map adapt . Map.toList   where-    adapt :: (Text, Expr s a) -> (NonEmpty Text, Expr s a)-    adapt (key, expression) =-        case shallowDenote expression of-            RecordLit m ->-                case fmap adapt (Map.toList $ recordFieldValue <$> m) of-                    [ (keys, expression') ] ->-                        (NonEmpty.cons key keys, expression')-                    _ ->-                        (pure key, RecordLit m)-            _ ->-                (pure key, expression)+    adapt :: (Text, RecordField Src a) -> KeyValue Src a+    adapt (key, RecordField mSrc0 val mSrc1 mSrc2)+        | not (containsComment mSrc2)+        , RecordLit m <- shallowDenote val+        , [ KeyValue keys mSrc2' val' ] <- map adapt (Map.toList m) =+            KeyValue (NonEmpty.cons (mSrc0, key, mSrc1) keys) mSrc2' val'+        | otherwise =+            KeyValue (pure (mSrc0, key, mSrc1)) mSrc2 val --- | Escape a `Text` literal using Dhall's escaping rules for single-quoted---   @Text@+-- | Escape a `Data.Text.Text` literal using Dhall's escaping rules for+--   single-quoted @Text@ escapeSingleQuotedText :: Text -> Text escapeSingleQuotedText inputText = outputText   where@@ -1541,7 +1649,7 @@      substitute before after = Text.intercalate after . Text.splitOn before -{-| Escape a `Text` literal using Dhall's escaping rules+{-| Escape a `Data.Text.Text` literal using Dhall's escaping rules      Note that the result does not include surrounding quotes -}
src/Dhall/Pretty/Internal.hs-boot view
@@ -2,6 +2,7 @@  import Data.Text (Text) import Data.Text.Prettyprint.Doc (Pretty, Doc)+import Dhall.Src (Src)  import {-# SOURCE #-} Dhall.Syntax @@ -14,3 +15,5 @@ prettyExpr :: Pretty a => Expr s a -> Doc Ann  prettyEnvironmentVariable :: Text -> Doc ann++prettyImportExpression :: Pretty a => Expr Src a -> Doc Ann
src/Dhall/Schemas.hs view
@@ -185,7 +185,7 @@                  let defaultedRecord = RecordLit defaultedKeyValues -                return (RecordCompletion (Field "schemas" name) defaultedRecord)+                return (RecordCompletion (Field "schemas" $ Core.makeFieldSelection name) defaultedRecord)         schemasRewrite subExpression =             subExpression 
src/Dhall/Set.hs view
@@ -75,33 +75,35 @@ toSeq :: Set a -> Seq a toSeq (Set _ xs) = xs --- | Convert a `Set` to a list, preserving the original order of the elements+{-| Convert a `Dhall.Set.Set` to a list, preserving the original order of the+    elements+-} toList :: Set a -> [a] toList (Set _ xs) = Data.Foldable.toList xs --- | Convert a `Set` to a list of ascending elements+-- | Convert a `Dhall.Set.Set` to a list of ascending elements toAscList :: Set a -> [a] toAscList (Set s _) = Data.Set.toAscList s --- | Convert a list to a `Set`, remembering the element order+-- | Convert a list to a `Dhall.Set.Set`, remembering the element order fromList :: Ord a => [a] -> Set a fromList = foldl' (flip append) empty -- O(n log n) time complexity, O(n) space complexity. -- Implementing it this way is a little silly, but is faster than (nub xs). -- n.b. toList . fromList = id, only if the list elements are unique --- | Convert a @"Data.Set".`Data.Set.Set`@ to a sorted `Set`+-- | Convert a @"Data.Set".`Data.Set.Set`@ to a sorted `Dhall.Set.Set` fromSet :: Data.Set.Set a -> Set a fromSet s = Set s (Data.Sequence.fromList (Data.Set.elems s)) --- | Append an element to the end of a `Set`+-- | Append an element to the end of a `Dhall.Set.Set` append :: Ord a => a -> Set a -> Set a append x os@(Set s xs)     | Data.Set.member x s = os     | otherwise = Set (Data.Set.insert x s) (xs |> x) -- O(log n) time complexity. --- | The empty `Set`+-- | The empty `Dhall.Set.Set` empty :: Set a empty = Set Data.Set.empty Data.Sequence.empty 
src/Dhall/Syntax.hs view
@@ -6,6 +6,7 @@ {-# LANGUAGE LambdaCase         #-} {-# LANGUAGE OverloadedLists    #-} {-# LANGUAGE OverloadedStrings  #-}+{-# LANGUAGE PatternSynonyms    #-} {-# LANGUAGE RankNTypes         #-} {-# LANGUAGE RecordWildCards    #-} {-# LANGUAGE StandaloneDeriving #-}@@ -29,6 +30,10 @@     , Expr(..)     , RecordField(..)     , makeRecordField+    , FunctionBinding(..)+    , makeFunctionBinding+    , FieldSelection(..)+    , makeFieldSelection      -- ** 'Let'-blocks     , MultiLet(..)@@ -41,6 +46,7 @@     , chunkExprs     , bindingExprs     , recordFieldExprs+    , functionBindingExprs      -- ** Handling 'Note's     , denote@@ -63,7 +69,7 @@     , reservedIdentifiers     , reservedKeywords -    -- * `Text` manipulation+    -- * `Data.Text.Text` manipulation     , toDoubleQuoted     , longestSharedWhitespacePrefix     , linesLiteral@@ -74,6 +80,9 @@      -- * Utilities     , internalError+    -- `shift` should really be in `Dhall.Normalize`, but it's here to avoid a+    -- module cycle+    , shift     ) where  import Control.DeepSeq            (NFData)@@ -139,7 +148,7 @@  {-| Label for a bound variable -    The `Text` field is the variable's name (i.e. \"@x@\").+    The `Data.Text.Text` field is the variable's name (i.e. \"@x@\").      The `Int` field disambiguates variables with the same name if there are     multiple bound variables of the same name in scope.  Zero refers to the@@ -166,7 +175,7 @@ >                               v           │ > λ(x : Type) → λ(y : Type) → λ(x : Type) → x -    Zero indices are omitted when pretty-printing `Var`s and non-zero indices+    Zero indices are omitted when pretty-printing @Var@s and non-zero indices     appear as a numeric suffix. -} data Var = V Text !Int@@ -285,41 +294,136 @@  For example, -> { {- A -} x : T }+> { {- A -} x {- B -} : {- C -} T }  ... or -> { {- A -} x = T }+> { {- A -} x {- B -} = {- C -} T }  will be instantiated as follows: -* @recordFieldSrc@ corresponds to the @A@ comment.-* @field@ is @"T"@+* @recordFieldSrc0@ corresponds to the @A@ comment.+* @recordFieldValue@ is @"T"@+* @recordFieldSrc1@ corresponds to the @B@ comment.+* @recordFieldSrc2@ corresponds to the @C@ comment.  Although the @A@ comment isn't annotating the @"T"@ Record Field,-this is the best place to keep these comments+this is the best place to keep these comments.++Note that @recordFieldSrc2@ is always 'Nothing' when the 'RecordField' is for+a punned entry, because there is no @=@ sign. For example,++> { {- A -} x {- B -} }++will be instantiated as follows:++* @recordFieldSrc0@ corresponds to the @A@ comment.+* @recordFieldValue@ corresponds to @(Var "x")@+* @recordFieldSrc1@ corresponds to the @B@ comment.+* @recordFieldSrc2@ will be 'Nothing'++The labels involved in a record using dot-syntax like in this example:++> { {- A -} a {- B -} . {- C -} b {- D -} . {- E -} c {- F -} = {- G -} e }++will be instantiated as follows:++* For both the @a@ and @b@ field, @recordfieldSrc2@ is 'Nothing'+* For the @a@ field:+  * @recordFieldSrc0@ corresponds to the @A@ comment+  * @recordFieldSrc1@ corresponds to the @B@ comment+* For the @b@ field:+  * @recordFieldSrc0@ corresponds to the @C@ comment+  * @recordFieldSrc1@ corresponds to the @D@ comment+* For the @c@ field:+  * @recordFieldSrc0@ corresponds to the @E@ comment+  * @recordFieldSrc1@ corresponds to the @F@ comment+  * @recordFieldSrc2@ corresponds to the @G@ comment++That is, for every label except the last one the semantics of @recordFieldSrc0@+and @recordFieldSrc1@ are the same from a regular record label but+@recordFieldSrc2@ is always 'Nothing'. For the last keyword, all srcs are 'Just' -} data RecordField s a = RecordField-    { recordFieldSrc  :: Maybe s+    { recordFieldSrc0  :: Maybe s     , recordFieldValue :: Expr s a+    , recordFieldSrc1  :: Maybe s+    , recordFieldSrc2  :: Maybe s     } deriving (Data, Eq, Foldable, Functor, Generic, Lift, NFData, Ord, Show, Traversable)  -- | Construct a 'RecordField' with no src information makeRecordField :: Expr s a -> RecordField s a-makeRecordField = RecordField Nothing+makeRecordField e = RecordField Nothing e Nothing Nothing   instance Bifunctor RecordField where-    first k (RecordField s0 value) =-        RecordField (k <$> s0) (first k value)+    first k (RecordField s0 value s1 s2) =+        RecordField (k <$> s0) (first k value) (k <$> s1) (k <$> s2)     second = fmap +{-| Record the label of a function or a function-type expression++For example,++> λ({- A -} a {- B -} : {- C -} T) -> e++will be instantiated as follows:+* @functionBindingSrc0@ corresponds to the @A@ comment+* @functionBindingVariable@ is @a@+* @functionBindingSrc1@ corresponds to the @B@ comment+* @functionBindingSrc2@ corresponds to the @C@ comment+* @functionBindingAnnotation@ is @T@+-}+data FunctionBinding s a = FunctionBinding+    { functionBindingSrc0 :: Maybe s+    , functionBindingVariable :: Text+    , functionBindingSrc1 :: Maybe s+    , functionBindingSrc2 :: Maybe s+    , functionBindingAnnotation :: Expr s a+    } deriving (Data, Eq, Foldable, Functor, Generic, Lift, NFData, Ord, Show, Traversable)++-- | Smart constructor for 'FunctionBinding' with no src information+makeFunctionBinding :: Text -> Expr s a -> FunctionBinding s a+makeFunctionBinding l t = FunctionBinding Nothing l Nothing Nothing t++instance Bifunctor FunctionBinding where+    first k (FunctionBinding src0 label src1 src2 type_) =+        FunctionBinding (k <$> src0) label (k <$> src1) (k <$> src2) (first k type_)++    second = fmap++{-| Record the field on a selector-expression++For example,++> e . {- A -} x {- B -}++will be instantiated as follows:+* @fieldSelectionSrc0@ corresponds to the @A@ comment+* @fieldSelectionLabel@ corresponds to @x@+* @fieldSelectionSrc1@ corresponds to the @B@ comment++Given our limitation that not all expressions recover their whitespaces, the+purpose of @fieldSelectionSrc1@ is to save the 'Text.Megaparsec.SourcePos' where+the @fieldSelectionLabel@ ends, but we /still/ use a 'Maybe Src' (@s = 'Src'@)+to be consistent with similar data types such as 'Binding', for example.+-}+data FieldSelection s = FieldSelection+    { fieldSelectionSrc0 :: Maybe s+    , fieldSelectionLabel :: !Text+    , fieldSelectionSrc1 :: Maybe s+    } deriving (Data, Eq, Foldable, Functor, Generic, Lift, NFData, Ord, Show, Traversable)++-- | Smart constructor for 'FieldSelection' with no src information+makeFieldSelection :: Text -> FieldSelection s+makeFieldSelection t = FieldSelection Nothing t Nothing+ {-| Syntax tree for expressions      The @s@ type parameter is used to track the presence or absence of `Src`     spans: -    * If @s = `Src`@ then the code may contains `Src` spans (either in a `Noted`+    * If @s = `Src`@ then the code may contains `Src` spans (either in a `Note`       constructor or inline within another constructor, like `Let`)     * If @s = `Void`@ then the code has no `Src` spans @@ -334,8 +438,8 @@     -- | > Var (V x 0)                              ~  x     --   > Var (V x n)                              ~  x@n     | Var Var-    -- | > Lam x     A b                            ~  λ(x : A) -> b-    | Lam Text (Expr s a) (Expr s a)+    -- | > Lam (FunctionBinding _ "x" _ _ A) b      ~  λ(x : A) -> b+    | Lam (FunctionBinding s a) (Expr s a)     -- | > Pi "_" A B                               ~        A  -> B     --   > Pi x   A B                               ~  ∀(x : A) -> B     | Pi  Text (Expr s a) (Expr s a)@@ -499,8 +603,8 @@     -- | > ToMap x (Just t)                         ~  toMap x : t     --   > ToMap x  Nothing                         ~  toMap x     | ToMap (Expr s a) (Maybe (Expr s a))-    -- | > Field e x                                ~  e.x-    | Field (Expr s a) Text+    -- | > Field e (FieldSelection _ x _)              ~  e.x+    | Field (Expr s a) (FieldSelection s)     -- | > Project e (Left xs)                      ~  e.{ xs }     --   > Project e (Right t)                      ~  e.(t)     | Project (Expr s a) (Either (Set Text) (Expr s a))@@ -543,6 +647,8 @@   fmap f (Note s e1) = Note s (fmap f e1)   fmap f (Record a) = Record $ fmap f <$> a   fmap f (RecordLit a) = RecordLit $ fmap f <$> a+  fmap f (Lam fb e) = Lam (f <$> fb) (f <$> e)+  fmap f (Field a b) = Field (f <$> a) b   fmap f expression = Lens.over unsafeSubExpressions (fmap f) expression   {-# INLINABLE fmap #-} @@ -555,18 +661,24 @@     return = pure      expression >>= k = case expression of-        Embed a    -> k a-        Let a b    -> Let (adaptBinding a) (b >>= k)-        Note a b   -> Note a (b >>= k)-        Record a -> Record $ bindRecordKeyValues <$> a+        Embed a     -> k a+        Let a b     -> Let (adaptBinding a) (b >>= k)+        Note a b    -> Note a (b >>= k)+        Record a    -> Record $ bindRecordKeyValues <$> a         RecordLit a -> RecordLit $ bindRecordKeyValues <$> a+        Lam a b     -> Lam (adaptFunctionBinding a) (b >>= k)+        Field a b   -> Field (a >>= k) b         _ -> Lens.over unsafeSubExpressions (>>= k) expression       where-        bindRecordKeyValues (RecordField s0 e) = RecordField s0 (e >>= k)+        bindRecordKeyValues (RecordField s0 e s1 s2) =+            RecordField s0 (e >>= k) s1 s2          adaptBinding (Binding src0 c src1 d src2 e) =             Binding src0 c src1 (fmap adaptBindingAnnotation d) src2 (e >>= k) +        adaptFunctionBinding (FunctionBinding src0 label src1 src2 type_) =+            FunctionBinding src0 label src1 src2 (type_ >>= k)+         adaptBindingAnnotation (src3, f) = (src3, f >>= k)  instance Bifunctor Expr where@@ -575,6 +687,8 @@     first k (Let a b    ) = Let (first k a) (first k b)     first k (Record a   ) = Record $ first k <$> a     first k (RecordLit a) = RecordLit $ first k <$> a+    first k (Lam a b    ) = Lam (first k a) (first k b)+    first k (Field a b  ) = Field (first k a) (k <$> b)     first k  expression  = Lens.over unsafeSubExpressions (first k) expression      second = fmap@@ -644,6 +758,8 @@ subExpressions f (Let a b) = Let <$> bindingExprs f a <*> f b subExpressions f (Record a) = Record <$> traverse (recordFieldExprs f) a subExpressions f (RecordLit a) = RecordLit <$> traverse (recordFieldExprs f) a+subExpressions f (Lam fb e) = Lam <$> functionBindingExprs f fb <*> f e+subExpressions f (Field a b) = Field <$> f a <*> pure b subExpressions f expression = unsafeSubExpressions f expression {-# INLINABLE subExpressions #-} @@ -658,7 +774,6 @@     :: Applicative f => (Expr s a -> f (Expr t b)) -> Expr s a -> f (Expr t b) unsafeSubExpressions _ (Const c) = pure (Const c) unsafeSubExpressions _ (Var v) = pure (Var v)-unsafeSubExpressions f (Lam a b c) = Lam a <$> f b <*> f c unsafeSubExpressions f (Pi a b c) = Pi a <$> f b <*> f c unsafeSubExpressions f (App a b) = App <$> f a <*> f b unsafeSubExpressions f (Annot a b) = Annot <$> f a <*> f b@@ -720,7 +835,6 @@ unsafeSubExpressions f (RecordCompletion a b) = RecordCompletion <$> f a <*> f b unsafeSubExpressions f (Merge a b t) = Merge <$> f a <*> f b <*> traverse f t unsafeSubExpressions f (ToMap a t) = ToMap <$> f a <*> traverse f t-unsafeSubExpressions f (Field a b) = Field <$> f a <*> pure b unsafeSubExpressions f (Project a b) = Project <$> f a <*> traverse f b unsafeSubExpressions f (Assert a) = Assert <$> f a unsafeSubExpressions f (Equivalent a b) = Equivalent <$> f a <*> f b@@ -731,6 +845,8 @@ unsafeSubExpressions _ (Embed {}) = unhandledConstructor "Embed" unsafeSubExpressions _ (Record {}) = unhandledConstructor "Record" unsafeSubExpressions _ (RecordLit {}) = unhandledConstructor "RecordLit"+unsafeSubExpressions _ (Lam {}) = unhandledConstructor "Lam"+unsafeSubExpressions _ (Field {}) = unhandledConstructor "Field" {-# INLINABLE unsafeSubExpressions #-}  unhandledConstructor :: Text -> a@@ -763,11 +879,27 @@     :: Applicative f     => (Expr s a -> f (Expr s b))     -> RecordField s a -> f (RecordField s b)-recordFieldExprs f (RecordField s0 e) =+recordFieldExprs f (RecordField s0 e s1 s2) =     RecordField         <$> pure s0         <*> f e+        <*> pure s1+        <*> pure s2 +{-| Traverse over the immediate 'Expr' children in a 'FunctionBinding'.+-}+functionBindingExprs+    :: Applicative f+    => (Expr s a -> f (Expr s b))+    -> FunctionBinding s a -> f (FunctionBinding s b)+functionBindingExprs f (FunctionBinding s0 label s1 s2 type_) =+    FunctionBinding+        <$> pure s0+        <*> pure label+        <*> pure s1+        <*> pure s2+        <*> f type_+ -- | A traversal over the immediate sub-expressions in 'Chunks'. chunkExprs   :: Applicative f@@ -856,7 +988,8 @@         <>  queryDoc         <>  foldMap prettyHeaders headers       where-        prettyHeaders h = " using " <> Pretty.pretty h+        prettyHeaders h =+          " using " <> Pretty.unAnnotate (prettyImportExpression h)          File {..} = path @@ -990,14 +1123,19 @@     Combine _ b c -> Combine Nothing (denote b) (denote c)     Record a -> Record $ denoteRecordField <$> a     RecordLit a -> RecordLit $ denoteRecordField <$> a+    Lam a b -> Lam (denoteFunctionBinding a) (denote b)+    Field a (FieldSelection _ b _) -> Field (denote a) (FieldSelection Nothing b Nothing)     expression -> Lens.over unsafeSubExpressions denote expression   where-    denoteRecordField (RecordField _ e) = RecordField Nothing (denote e)+    denoteRecordField (RecordField _ e _ _) = RecordField Nothing (denote e) Nothing Nothing     denoteBinding (Binding _ c _ d _ e) =         Binding Nothing c Nothing (fmap denoteBindingAnnotation d) Nothing (denote e)      denoteBindingAnnotation (_, f) = (Nothing, denote f) +    denoteFunctionBinding (FunctionBinding _ l _ _ t) =+        FunctionBinding Nothing l Nothing Nothing (denote t)+ -- | The \"opposite\" of `denote`, like @first absurd@ but faster renote :: Expr Void a -> Expr s a renote = unsafeCoerce@@ -1012,7 +1150,7 @@ shallowDenote (Note _ e) = shallowDenote e shallowDenote         e  = e --- | The set of reserved keywords according to the `keyword` rule in the grammar+-- | The set of reserved keywords according to the @keyword@ rule in the grammar reservedKeywords :: HashSet Text reservedKeywords =     Data.HashSet.fromList@@ -1170,17 +1308,114 @@      indent = Data.Text.length longestSharedPrefix +{-| `shift` is used by both normalization and type-checking to avoid variable+    capture by shifting variable indices++    For example, suppose that you were to normalize the following expression:++> λ(a : Type) → λ(x : a) → (λ(y : a) → λ(x : a) → y) x++    If you were to substitute @y@ with @x@ without shifting any variable+    indices, then you would get the following incorrect result:++> λ(a : Type) → λ(x : a) → λ(x : a) → x  -- Incorrect normalized form++    In order to substitute @x@ in place of @y@ we need to `shift` @x@ by @1@ in+    order to avoid being misinterpreted as the @x@ bound by the innermost+    lambda.  If we perform that `shift` then we get the correct result:++> λ(a : Type) → λ(x : a) → λ(x : a) → x@1++    As a more worked example, suppose that you were to normalize the following+    expression:++>     λ(a : Type)+> →   λ(f : a → a → a)+> →   λ(x : a)+> →   λ(x : a)+> →   (λ(x : a) → f x x@1) x@1++    The correct normalized result would be:++>     λ(a : Type)+> →   λ(f : a → a → a)+> →   λ(x : a)+> →   λ(x : a)+> →   f x@1 x++    The above example illustrates how we need to both increase and decrease+    variable indices as part of substitution:++    * We need to increase the index of the outer @x\@1@ to @x\@2@ before we+      substitute it into the body of the innermost lambda expression in order+      to avoid variable capture.  This substitution changes the body of the+      lambda expression to @(f x\@2 x\@1)@++    * We then remove the innermost lambda and therefore decrease the indices of+      both @x@s in @(f x\@2 x\@1)@ to @(f x\@1 x)@ in order to reflect that one+      less @x@ variable is now bound within that scope++    Formally, @(shift d (V x n) e)@ modifies the expression @e@ by adding @d@ to+    the indices of all variables named @x@ whose indices are greater than+    @(n + m)@, where @m@ is the number of bound variables of the same name+    within that scope++    In practice, @d@ is always @1@ or @-1@ because we either:++    * increment variables by @1@ to avoid variable capture during substitution+    * decrement variables by @1@ when deleting lambdas after substitution++    @n@ starts off at @0@ when substitution begins and increments every time we+    descend into a lambda or let expression that binds a variable of the same+    name in order to avoid shifting the bound variables by mistake.+-}+shift :: Int -> Var -> Expr s a -> Expr s a+shift d (V x n) (Var (V x' n')) = Var (V x' n'')+  where+    n'' = if x == x' && n <= n' then n' + d else n'+shift d (V x n) (Lam (FunctionBinding src0 x' src1 src2 _A) b) =+    Lam (FunctionBinding src0 x' src1 src2 _A') b'+  where+    _A' = shift d (V x n ) _A+    b'  = shift d (V x n') b+      where+        n' = if x == x' then n + 1 else n+shift d (V x n) (Pi x' _A _B) = Pi x' _A' _B'+  where+    _A' = shift d (V x n ) _A+    _B' = shift d (V x n') _B+      where+        n' = if x == x' then n + 1 else n+shift d (V x n) (Let (Binding src0 f src1 mt src2 r) e) =+    Let (Binding src0 f src1 mt' src2 r') e'+  where+    e' = shift d (V x n') e+      where+        n' = if x == f then n + 1 else n++    mt' = fmap (fmap (shift d (V x n))) mt+    r'  =             shift d (V x n)  r+shift d v expression = Lens.over subExpressions (shift d v) expression+ -- | Desugar all @with@ expressions desugarWith :: Expr s a -> Expr s a desugarWith = Optics.rewriteOf subExpressions rewrite   where     rewrite e@(With record (key :| []) value) =-        Just (Prefer (PreferFromWith e) record (RecordLit [ (key, makeRecordField value) ]))+        Just+            (Prefer+                (PreferFromWith e)+                record+                (RecordLit [ (key, makeRecordField value) ])+            )     rewrite e@(With record (key0 :| key1 : keys) value) =         Just-            (Prefer (PreferFromWith e) record-                (RecordLit-                    [ (key0, makeRecordField $ With (Field record key0) (key1 :| keys) value) ]+            (Let+                (makeBinding "_" record)+                (Prefer (PreferFromWith e) "_"+                    (RecordLit+                        [ (key0, makeRecordField $ With (Field "_" (FieldSelection Nothing key0 Nothing)) (key1 :| keys) (shift 1 "_" value)) ]+                    )                 )             )     rewrite _ = Nothing
src/Dhall/TH.hs view
@@ -58,8 +58,8 @@      > < This : Natural | Other : ../Other/Type.dhall > -    ... rather than duplicating the AST manually in a Haskell `Type`, you can-    do:+    ... rather than duplicating the AST manually in a Haskell `Dhall.Type`, you+    can do:      > Dhall.Type     > (\case@@ -363,7 +363,7 @@ -- -- By default, the generated types only derive `GHC.Generics.Generic`, -- `Dhall.FromDhall`, and `Dhall.ToDhall`.  To add any desired instances (such--- as `Eq`\/`Ord`\/`Show`), you can use the `StandaloneDeriving` language+-- as `Eq`\/`Ord`\/`Show`), you can use the @StandaloneDeriving@ language -- extension, like this: -- -- > {-# LANGUAGE DeriveAnyClass     #-}
src/Dhall/Tags.hs view
@@ -111,11 +111,11 @@     _ -> mempty  {-| Used to update tag position and to build tag from term.-    After getTagsFromExpr line and column in line are in `LineColumn` for each tag.+    After getTagsFromExpr line and column in line are in @LineColumn@ for each tag.     And tagPattern is not added.     Emacs use tag pattern to check if tag is on line. It compares line from start     with tag pattern and in case they are the same, relocate user.-    fixPosAndDefinition change position to line and byte offset (`LineOffset`) and+    fixPosAndDefinition change position to line and byte offset (@LineOffset@) and     add tag pattern. For example, for Dhall string:      >>> let dhallSource = "let foo = \"bar\"\nlet baz = \"qux\""@@ -161,7 +161,7 @@           lengthInBytes = BS.length . encodeUtf8            {-| get information about term from map of lines-              In most cases, `LineColumn` after `getTagsFromExpr` points to byte before term.+              In most cases, @LineColumn@ after `getTagsFromExpr` points to byte before term.               It's better to have term in term pattern, so this function finds and updates               line number and byte offset and generate pattern.           -}
src/Dhall/Tutorial.hs view
@@ -148,8 +148,8 @@ -- >>> input auto "True" :: IO Bool -- True ----- The `input` function can decode any value if we specify the value's expected--- `Type`:+-- The `Dhall.input` function can decode any value if we specify the value's+-- expected `Dhall.Type`: -- -- > input -- >     :: Type a  -- Expected type@@ -180,7 +180,7 @@ -- You can see what types `auto` supports \"out-of-the-box\" by browsing the -- instances for the `FromDhall` class.  For example, the following instance -- says that we can directly decode any Dhall expression that evaluates to a--- @Bool@ into a Haskell `Bool`:+-- @Bool@ into a Haskell `Prelude.Bool`: -- -- > instance FromDhall Bool --@@ -198,8 +198,8 @@ -- >>> input auto "[True, False]" :: IO (Vector Bool) -- [True,False] ----- We could also specify what type to decode by providing an explicit `Type`--- instead of using `auto` with a type annotation:+-- We could also specify what type to decode by providing an explicit+-- `Dhall.Type` instead of using `auto` with a type annotation: -- -- >>> input (vector bool) "[True, False]" -- [True,False]@@ -253,7 +253,7 @@ -- ... -- -- The interpreter complains because the string @\"1\"@ cannot be decoded into a--- Haskell value of type `Bool`.  This part of the type error:+-- Haskell value of type `Prelude.Bool`.  This part of the type error: -- -- > - Bool -- > + Natural@@ -594,7 +594,7 @@ -- using the @dhall@ command. -- -- You can convert a record to a list of key-value pairs (a.k.a. a \"Map\") by--- using the `toMap` keyword.  For example:+-- using the @toMap@ keyword.  For example: -- -- > $ dhall <<< 'toMap { foo = 1, bar = 2 }' -- > [ { mapKey = "bar", mapValue = 2 }, { mapKey = "foo", mapValue = 1 } ]@@ -614,14 +614,17 @@ -- >     [ n && True, n && False, n || True, n || False ] -- -- ... or we can use Dhall's support for Unicode characters to use @λ@ (U+03BB)--- instead of @\\@ and @→@ (U+2192) instead of @->@ (for people who are into that--- sort of thing):+-- instead of @\\@ and @→@ (U+2192) instead of @->@ (for people who are into+-- that sort of thing): -- -- > $ -- ./makeBools.dhall -- > λ(n : Bool) → -- >     [ n && True, n && False, n || True, n || False ] -- > <Ctrl-D> --+-- We'll be sticking to ASCII for the remainder of the tutorial, though, while+-- still pointing out Unicode equivalents as we go.+-- -- You can read this as a function of one argument named @n@ that has type -- @Bool@.  This function returns a @List@ of @Bool@s.  Each element of the -- @List@ depends on the input argument named @n@.@@ -644,7 +647,7 @@ -- Thanks to currying, this instance works for functions of multiple simple -- arguments: ----- >>> dhallAnd <- input auto "λ(x : Bool) → λ(y : Bool) → x && y" :: IO (Bool -> Bool -> Bool)+-- >>> dhallAnd <- input auto "\\(x : Bool) -> \\(y : Bool) -> x && y" :: IO (Bool -> Bool -> Bool) -- >>> dhallAnd True False -- False --@@ -666,7 +669,7 @@ -- >     deriving (Generic, ToDhall) -- > -- > main = do--- >     f <- input auto "λ(r : { foo : Bool, bar : Bool }) → r.foo && r.bar"+-- >     f <- input auto "\\(r : { foo : Bool, bar : Bool }) -> r.foo && r.bar" -- >     print (f (Example0 { foo = True, bar = False }) :: Bool) -- >     print (f (Example0 { foo = True, bar = True  }) :: Bool) --@@ -686,6 +689,12 @@ -- > $ dhall --annotate <<< './makeBools.dhall' -- > (λ(n : Bool) → [ n, False, True, n ]) : ∀(n : Bool) → List Bool --+-- The @dhall@ command emits Unicode output by default, but you can switch to+-- ASCII output using the @--ascii@ flag:+--+-- > $ dhall --annotate --ascii <<< './makeBools.dhall'+-- > (\(n : Bool) -> [ n, False, True, n ]) : forall (n : Bool) -> List Bool+-- -- The @--annotate@ flag adds a type signature to the output to let us know -- what type the interpreter inferred for our expression.  The type signature -- is @∀(n : Bool) → List Bool@ which says that @makeBools@ is a function of one@@ -693,16 +702,16 @@ -- @Bool@s.  The @∀@ (U+2200) symbol is shorthand for the ASCII @forall@ -- keyword: ----- > ∀(x : a) → b        -- This type ...+-- > ∀(x : a) → b         -- This type ... -- >--- > forall (x : a) → b  -- ... is the same as this type+-- > forall (x : a) -> b  -- ... is the same as this type -- -- ... and Dhall's @forall@ keyword behaves the same way as Haskell's @forall@ -- keyword for input values that are @Type@s: ----- > forall (x : Type) → b  -- This Dhall type ...+-- > forall (x : Type) -> b  -- This Dhall type ... ----- > forall x . b           -- ... is the same as this Haskell type+-- > forall x . b            -- ... is the same as this Haskell type -- -- The part where Dhall differs from Haskell is that you can also use -- @∀@/@forall@ to give names to non-@Type@ arguments (such as the first@@ -734,7 +743,7 @@ -- Remember that file paths are synonymous with their contents, so the above -- code is exactly equivalent to: ----- > $ dhall <<< '(λ(n : Bool) → [n && True, n && False, n || True, n || False]) True'+-- > $ dhall <<< '(\(n : Bool) -> [n && True, n && False, n || True, n || False]) True' -- > [True, False, True, True] -- -- When you apply an anonymous function to an argument, you substitute the@@ -742,9 +751,9 @@ -- -- >    Bound variable -- >    ⇩--- > (λ(n : Bool) → ...) True--- >                     ⇧--- >                     Function argument+-- > (\(n : Bool) -> ...) True+-- >                      ⇧+-- >                      Function argument -- -- So in our above example, we would replace all occurrences of @n@ with @True@, -- like this:@@ -767,7 +776,7 @@ -- __Exercise__: Create a file named @getFoo@ that is a function of the following -- type: ----- > ∀(r : { foo : Bool, bar : Text }) → Bool+-- > forall (r : { foo : Bool, bar : Text }) -> Bool -- -- This function should take a single input argument named @r@ that is a record -- with two fields.  The function should return the value of the @foo@ field.@@ -878,7 +887,7 @@ -- ... but fails with a type error if either shared field is not a record: -- -- > $ dhall--- > { foo = 1, bar = "ABC" } ∧ { foo = True }+-- > { foo = 1, bar = "ABC" } /\ { foo = True } -- > <Ctrl-D> -- > Use "dhall --explain" for detailed errors -- >@@ -894,7 +903,7 @@ -- You can analogously combine record types using the @//\\\\@ operator (or @(⩓)@ U+2A53): -- -- > $ dhall--- > { foo : Natural } ⩓ { bar : Text }+-- > { foo : Natural } //\\ { bar : Text } -- > <Ctrl-D> -- > { foo : Natural, bar : Text } --@@ -902,7 +911,7 @@ -- operator descends recursively into record types: -- -- > $ dhall--- > { foo : { bar : Text } } ⩓ { foo : { baz : Bool }, qux : Natural }+-- > { foo : { bar : Text } } //\\ { foo : { baz : Bool }, qux : Natural } -- > <Ctrl-D> -- > { foo : { bar : Text, baz : Bool }, qux : Natural } @@ -941,7 +950,7 @@ -- function: -- -- > $ dhall--- > let twice = λ(x : Text) → x ++ x in twice "ha"+-- > let twice = \(x : Text) -> x ++ x in twice "ha" -- > <Ctrl-D> -- > "haha" --@@ -1092,10 +1101,10 @@ -- would write: -- -- > $ cat > process <<EOF--- >     λ(union : < Left : Natural | Right : Bool >)--- > →   let handlers =+-- >   \(union : < Left : Natural | Right : Bool >) ->+-- >     let handlers = -- >             { Left  = Natural/even  -- Natural/even is a built-in function--- >             , Right = λ(b : Bool) → b+-- >             , Right = \(b : Bool) -> b -- >             } -- > in  merge handlers union -- > EOF@@ -1125,14 +1134,14 @@ -- -- So, for example: ----- > merge { Left = Natural/even, Right = λ(b : Bool) → b } (< Left : Natural | Right : Bool >.Left 3)+-- > merge { Left = Natural/even, Right = \(b : Bool) -> b } (< Left : Natural | Right : Bool >.Left 3) -- >     = Natural/even 3 -- >     = False -- -- ... and similarly: ----- > merge { Left = Natural/even, Right = λ(b : Bool) → b } (< Left : Natural | Right : Bool >.Right True)--- >     = (λ(b : Bool) → b) True+-- > merge { Left = Natural/even, Right = \(b : Bool) -> b } (< Left : Natural | Right : Bool >.Right True)+-- >     = (\(b : Bool) -> b) True -- >     = True -- -- Notice that each handler has to return the same type of result (@Bool@ in@@ -1165,13 +1174,13 @@ -- ... and when you @merge@ an empty alternative the correspond handler takes no -- argument: ----- >     λ(x : < Empty | Person : { name : Text, age : Natural } >)--- > →   merge--- >     {   Empty = "Unknown"  -- Note the absence of a `λ`+-- > \(x : < Empty | Person : { name : Text, age : Natural } >) ->+-- >   merge+-- >     { Empty = "Unknown"  -- Note the absence of an anonymous function -- >--- >     ,   Person =--- >             λ(person : { name : Text, age : Natural })--- >         →   "Name: ${person.name}, Age: ${Natural/show person.age}"+-- >     , Person =+-- >         \(person : { name : Text, age : Natural }) ->+-- >           "Name: ${person.name}, Age: ${Natural/show person.age}" -- >     } -- >     x --@@ -1203,14 +1212,14 @@ -- -- The equivalent function in Dhall is: ----- > λ(a : Type) → λ(x : a) → x+-- > \(a : Type) -> \(x : a) -> x -- -- Notice how this function takes two arguments instead of one.  The first -- argument is the type of the second argument. -- -- Let's illustrate how this works by actually using the above function: ----- > $ echo "λ(a : Type) → λ(x : a) → x" > id+-- > $ echo "\\(a : Type) -> \\(x : a) -> x" > id -- -- Let's ask the interpreter for the type of this function: -- the first line:@@ -1280,7 +1289,7 @@ -- argument type then that means that the name of the argument is @"_"@.  This -- is true even for user-defined functions: ----- > $ dhall type <<< 'λ(_ : Text) → 1'+-- > $ dhall type <<< '\\(_ : Text) -> 1' -- > Text → Natural -- -- The type @Text → Natural@ is the same as @∀(_ : Text) → Natural@@@ -1313,8 +1322,8 @@ -- complex example: -- -- > $ dhall--- >     let List/map = https://prelude.dhall-lang.org/List/map--- > in  λ(f : Natural → Natural) → List/map Natural Natural f [1, 2, 3]+-- > let List/map = https://prelude.dhall-lang.org/List/map+-- > in  \(f : Natural → Natural) -> List/map Natural Natural f [1, 2, 3] -- > <Ctrl-D> -- > λ(f : Natural → Natural) → [f 1, f 2, f 3] --@@ -1348,8 +1357,8 @@ -- code.  For example, we can add some tests to our @not@ function like this: -- -- > let not--- >     : Bool → Bool--- >     = λ(b : Bool) → b == False+-- >     : Bool -> Bool+-- >     = \(b : Bool) -> b == False -- > -- > let example0 = assert : not False === True -- >@@ -1366,8 +1375,8 @@ -- > -- ./test.dhall -- > -- > let not--- >     : Bool → Bool--- >     = λ(b : Bool) → b == False+-- >     : Bool -> Bool+-- >     = \(b : Bool) -> b == False -- > -- > let example0 = assert : not False === True -- >@@ -1528,7 +1537,7 @@ -- From Dhall's point of view, the hash is the true address and the file path -- is just a suggestion for how to obtain the import if it's not already cached. ----- You can disable the cache by setting `XDG_CACHE_HOME` to `/var/empty` (an+-- You can disable the cache by setting @XDG_CACHE_HOME@ to `/var/empty` (an -- empty and unwritable directory), like this: -- -- > $ XDG_CACHE_HOME=/var/empty dhall <<< './foo'@@ -1620,8 +1629,8 @@ -- $rawText -- -- Sometimes you want to import the contents of a raw text file as a Dhall--- value of type `Text`.  For example, one of the fields of a record might be--- the contents of a software license:+-- value of type `Dhall.Syntax.Text`.  For example, one of the fields of a+-- record might be the contents of a software license: -- -- > { package = "dhall" -- > , author  = "Gabriel Gonzalez"@@ -1684,30 +1693,30 @@ -- ... and run the expression through the formatter: -- -- > $ dhall format < ./unformatted--- >   λ(a : Type)--- > → λ(kvss : List (List { index : Natural, value : a }))--- > → List/build+-- > λ(a : Type) →+-- > λ(kvss : List (List { index : Natural, value : a })) →+-- >   List/build -- >     { index : Natural, value : a }--- >     (   λ(list : Type)--- >       → λ(cons : { index : Natural, value : a } → list → list)--- >       → λ(nil : list)--- >       → ( List/fold+-- >     ( λ(list : Type) →+-- >       λ(cons : { index : Natural, value : a } → list → list) →+-- >       λ(nil : list) →+-- >         ( List/fold -- >             (List { index : Natural, value : a }) -- >             kvss -- >             { count : Natural, diff : Natural → list }--- >             (   λ(kvs : List { index : Natural, value : a })--- >               → λ(y : { count : Natural, diff : Natural → list })--- >               → { count =+-- >             ( λ(kvs : List { index : Natural, value : a }) →+-- >               λ(y : { count : Natural, diff : Natural → list }) →+-- >                 { count = -- >                     y.count + List/length { index : Natural, value : a } kvs -- >                 , diff =--- >                       λ(n : Natural)--- >                     → List/fold+-- >                     λ(n : Natural) →+-- >                       List/fold -- >                         { index : Natural, value : a } -- >                         kvs -- >                         list--- >                         (   λ(kvOld : { index : Natural, value : a })--- >                           → λ(z : list)--- >                           → cons+-- >                         ( λ(kvOld : { index : Natural, value : a }) →+-- >                           λ(z : list) →+-- >                             cons -- >                               { index = kvOld.index + n, value = kvOld.value } -- >                               z -- >                         )@@ -1880,7 +1889,7 @@ -- new built-in functions.  This section contains a simple Haskell recipe to add -- a new @Natural/equal@ built-in function of type: ----- > Natural/equal : Natural → Natural → Bool+-- > Natural/equal : Natural -> Natural -> Bool -- -- To do so, we: --@@ -2030,10 +2039,10 @@ -- The @not@ function is just a UTF8-encoded text file hosted online with the -- following contents ----- > $ $ dhall <<< 'https://prelude.dhall-lang.org/Bool/not as Text'+-- > $ dhall <<< 'https://prelude.dhall-lang.org/Bool/not as Text' -- > '' -- > {---- > Flip the value of a `Bool`+-- > Flip the value of a Bool -- > -} -- > let not : Bool → Bool = λ(b : Bool) → b == False -- >@@ -2237,10 +2246,10 @@ -- convenience: -- -- > $ dhall--- >     let Prelude = https://prelude.dhall-lang.org/package.dhall+-- > let Prelude = https://prelude.dhall-lang.org/package.dhall -- >--- > in    λ(x : Text)--- >     → Prelude.List.length Text (Prelude.List.replicate 10 Text x)+-- > in  \(x : Text) ->+-- >       Prelude.List.length Text (Prelude.List.replicate 10 Text x) -- > <Ctrl-D> -- > ∀(x : Text) → Natural -- >
src/Dhall/TypeCheck.hs view
@@ -3,6 +3,7 @@ {-# LANGUAGE RankNTypes          #-} {-# LANGUAGE RecordWildCards     #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE ViewPatterns        #-}  {-# OPTIONS_GHC -Wall #-} @@ -56,6 +57,7 @@     , Chunks (..)     , Const (..)     , Expr (..)+    , FunctionBinding (..)     , PreferAnnotation (..)     , RecordField (..)     , Var (..)@@ -184,19 +186,19 @@ fresh :: Ctx a -> Text -> Val a fresh Ctx{..} x = VVar x (Eval.countNames x (Eval.envNames values)) -{-| `typeWithA` is implemented internally in terms of `infer` in order to speed+{-| `typeWithA` is implemented internally in terms of @infer@ in order to speed     up equivalence checking. -    Specifically, we extend the `Context` to become a `Ctx`, which can store +    Specifically, we extend the `Context` to become a @Ctx@, which can store      the entire contents of a `let` expression (i.e. the type *and* the value-    of the bound variable).  By storing this extra information in the `Ctx` we+    of the bound variable).  By storing this extra information in the @Ctx@ we     no longer need to substitute `let` expressions at all (which is very     expensive!).      However, this means that we need to use `Dhall.Eval.conv` to perform     equivalence checking instead of `Dhall.Core.judgmentallyEqual` since-    only `judgmentallyEqual` is unable to use the information stored in the-    extended context for accurate equivalence checking.+    only `Dhall.Core.judgmentallyEqual` is unable to use the information stored+    in the extended context for accurate equivalence checking. -} infer     :: forall a s@@ -227,7 +229,7 @@              go types n0 -        Lam x _A b -> do+        Lam (FunctionBinding { functionBindingVariable = x, functionBindingAnnotation = _A}) b -> do             tA' <- loop ctx _A              case tA' of@@ -732,7 +734,7 @@             return (VOptional _A')          Record xTs -> do-            let process x (RecordField _ _T) = do+            let process x (RecordField {recordFieldValue = _T}) = do                     tT' <- lift (loop ctx _T)                      case tT' of@@ -907,9 +909,12 @@                   | not (Dhall.Map.member "Type" xLs')                      -> die (InvalidRecordCompletion "Type" l)                   | otherwise-                     -> loop ctx (Annot (Prefer PreferFromCompletion (Field l "default") r) (Field l "Type"))+                     -> loop ctx (Annot (Prefer PreferFromCompletion (Field l def) r) (Field l typ))                 _ -> die (CompletionSchemaMustBeARecord l (quote names _L')) +              where+                def = Syntax.makeFieldSelection "default"+                typ = Syntax.makeFieldSelection "Type"         Merge t u mT₁ -> do             _T' <- loop ctx t @@ -1112,7 +1117,7 @@                         die (MapTypeMismatch (quote names (mapType _T')) _T₁'') -        Field e x -> do+        Field e (Syntax.fieldSelectionLabel -> x) -> do             _E' <- loop ctx e              let _E'' = quote names _E'@@ -4504,7 +4509,7 @@         _        -> mempty  {-| Wrap a type error in this exception type to censor source code and-    `Text` literals from the error message+    `Dhall.Syntax.Text` literals from the error message -} data Censored     = CensoredDetailed (DetailedTypeError Src X)
src/Dhall/Version.hs view
@@ -8,7 +8,7 @@ import qualified Data.Version as V import qualified Paths_dhall  as P --- | The current `Version` of the Haskell implementation+-- | The current `V.Version` of the Haskell implementation dhallVersion :: V.Version dhallVersion = P.version 
tests/Dhall/Test/Dhall.hs view
@@ -13,23 +13,25 @@  module Dhall.Test.Dhall where -import Control.Exception  (SomeException, try)-import Data.Fix           (Fix (..))-import Data.List.NonEmpty (NonEmpty (..))-import Data.Maybe         (isJust)-import Data.Scientific    (Scientific)-import Data.Sequence      (Seq)-import Data.Text          (Text)-import Data.Vector        (Vector)-import Data.Void          (Void)-import Dhall              (FromDhall, ToDhall)-import Dhall.Core         (Expr (..))-import GHC.Generics       (Generic, Rep)-import Numeric.Natural    (Natural)-import System.Timeout     (timeout)+import Control.Exception    (SomeException, try)+import Data.Fix             (Fix (..))+import Data.Functor.Classes (Eq1(..), Show1(..))+import Data.List.NonEmpty   (NonEmpty (..))+import Data.Maybe           (isJust)+import Data.Scientific      (Scientific)+import Data.Sequence        (Seq)+import Data.Text            (Text)+import Data.Vector          (Vector)+import Data.Void            (Void)+import Dhall                (FromDhall, ToDhall)+import Dhall.Core           (Expr (..))+import GHC.Generics         (Generic, Rep)+import Numeric.Natural      (Natural)+import System.Timeout       (timeout) import Test.Tasty import Test.Tasty.HUnit +import qualified Data.Functor.Classes as Classes import qualified Data.Text.Lazy import qualified Dhall import qualified Dhall.Core@@ -43,6 +45,17 @@    | MulF expr expr    deriving (Eq, Functor, Generic, FromDhall, Show) +instance Eq1 ExprF where+    liftEq _  (LitF aL) (LitF aR) = aL == aR+    liftEq eq (AddF aL bL) (AddF aR bR) = (aL `eq` aR) && (bL `eq` bR)+    liftEq eq (MulF aL bL) (MulF aR bR) = (aL `eq` aR) && (bL `eq` bR)+    liftEq _ _ _ = False++instance Show1 ExprF where+    liftShowsPrec _  _ d (LitF a) = showsPrec d a+    liftShowsPrec sp _ d (AddF a b) = Classes.showsBinaryWith sp sp "AddF" d a b+    liftShowsPrec sp _ d (MulF a b) = Classes.showsBinaryWith sp sp "MulF" d a b+ tests :: TestTree tests =     testGroup "Input"@@ -116,9 +129,10 @@     let exampleEncoder :: Dhall.Encoder ()         exampleEncoder = Dhall.unionEncoder (Dhall.encodeConstructor "A") -    Dhall.embed exampleEncoder () @=? Field (Union (Dhall.Map.singleton "A" Nothing)) "A"+    let a = Dhall.Core.makeFieldSelection "A"+    Dhall.embed exampleEncoder () @=? Field (Union (Dhall.Map.singleton "A" Nothing)) a -data RecursiveType a = RecursiveType (RecursiveType a)+newtype RecursiveType a = RecursiveType (RecursiveType a)     deriving Generic  instance FromDhall (RecursiveType a)
tests/Dhall/Test/Format.hs view
@@ -17,7 +17,7 @@ import qualified Dhall.Pretty                          as Pretty import qualified Dhall.Test.Util                       as Test.Util import qualified Test.Tasty                            as Tasty-import qualified Test.Tasty.HUnit                      as Tasty.HUnit+import qualified Test.Tasty.Silver                     as Tasty.Silver import qualified Turtle  getTests :: IO TestTree@@ -55,22 +55,14 @@  formatTest :: CharacterSet -> Text -> TestTree formatTest characterSet prefix =-    Tasty.HUnit.testCase (Text.unpack prefix) $ do-        let inputFile  = Text.unpack (prefix <> "A.dhall")-        let outputFile = Text.unpack (prefix <> "B.dhall")--        inputText <- Text.IO.readFile inputFile--        headerAndExpr <- Core.throws (Parser.exprAndHeaderFromText mempty inputText)+    let inputFile  = Text.unpack (prefix <> "A.dhall")+        outputFile = Text.unpack (prefix <> "B.dhall") -        let actualText = format characterSet headerAndExpr-        expectedText <- Text.IO.readFile outputFile+        action = do+            inputText <- Text.IO.readFile inputFile -        let message =-                   "The formatted expression did not match the expected output\n"-                <> "Expected:\n\n" <> Text.unpack expectedText <> "\n\n"-                <> "Actual:\n\n" <> Text.unpack actualText <> "\n\n"-                <> "Expected (show): " <> show expectedText <> "\n"-                <> "Actual   (show): " <> show actualText <> "\n"+            headerAndExpr <- Core.throws (Parser.exprAndHeaderFromText mempty inputText) -        Tasty.HUnit.assertBool message (actualText == expectedText)+            return (format characterSet headerAndExpr)+    in+        Tasty.Silver.goldenVsAction (Text.unpack prefix) outputFile action id
tests/Dhall/Test/Import.hs view
@@ -36,6 +36,12 @@               --               --     URL: https://test.dhall-lang.org/Bool/package.dhall               importDirectory </> "success/headerForwardingA.dhall"+            , importDirectory </> "success/unit/RemoteAsTextA.dhall"+            , importDirectory </> "success/unit/SimpleRemoteA.dhall"+            , importDirectory </> "success/unit/asLocation/RemoteChain1A.dhall"+            , importDirectory </> "success/unit/asLocation/RemoteChain2A.dhall"+            , importDirectory </> "success/unit/asLocation/RemoteChain3A.dhall"+            , importDirectory </> "success/unit/asLocation/RemoteChainMissingA.dhall"             ]      successTests <- Test.Util.discover (Turtle.chars <> "A.dhall") successTest (do
tests/Dhall/Test/QuickCheck.hs view
@@ -37,8 +37,10 @@     , DhallDouble (..)     , Directory (..)     , Expr (..)+    , FieldSelection (..)     , File (..)     , FilePrefix (..)+    , FunctionBinding (..)     , Import (..)     , ImportHashed (..)     , ImportMode (..)@@ -60,7 +62,7 @@ import Dhall.Src                 (Src (..)) import Dhall.Test.Format         (format) import Dhall.TypeCheck           (TypeError, Typer)-import Generic.Random            ((:+) (..), W, Weights, (%), ConstrGen(..))+import Generic.Random            ((:+) (..), ConstrGen (..), W, Weights, (%)) import Test.QuickCheck     ( Arbitrary (..)     , Gen@@ -277,11 +279,22 @@             ]  instance (Arbitrary s, Arbitrary a) => Arbitrary (RecordField s a) where-    arbitrary =-        lift1 Dhall.Core.makeRecordField+    arbitrary = lift4 RecordField      shrink = genericShrink +instance (Arbitrary s, Arbitrary a) => Arbitrary (FunctionBinding s a) where+    arbitrary = do+        l <- label+        type_ <- arbitrary+        return $ FunctionBinding Nothing l Nothing Nothing type_++    shrink = genericShrink++instance Arbitrary s => Arbitrary (FieldSelection s) where+    arbitrary = FieldSelection <$> pure Nothing <*> label <*> pure Nothing+    shrink = genericShrink+ instance (Arbitrary s, Arbitrary a) => Arbitrary (Expr s a) where     arbitrary =         Test.QuickCheck.suchThat@@ -292,17 +305,17 @@             standardizedExpression       where         customGens-            :: ConstrGen "Lam" 0 Text+            :: ConstrGen "Lam" 0 (FunctionBinding s a)             :+ ConstrGen "Pi" 0 Text-            :+ ConstrGen "Field" 1 Text+            :+ ConstrGen "Field" 1 (FieldSelection s)             :+ ConstrGen "Project" 1 (Either (Set Text) (Expr s a))             :+ Gen Integer  -- Generates all Integer fields in Expr             :+ Gen Text     -- Generates all Text fields in Expr             :+ ()         customGens =-               ConstrGen label-            :+ ConstrGen label+               ConstrGen arbitrary             :+ ConstrGen label+            :+ ConstrGen arbitrary             :+ ConstrGen projection             :+ integer                -- 'Lam's and 'Pi's are encoded differently when the binding is@@ -445,7 +458,10 @@     arbitrary = do         lift2 Src <*> whitespace -    shrink _ = []+    shrink (Src start end text) =+            (Src <$> shrink start <*> pure end   <*> pure text)+        ++  (Src <$> pure start   <*> shrink end <*> pure text)+        ++  (Src <$> pure start   <*> pure end   <*> shrinkWhitespace text)  instance Arbitrary SourcePos where     arbitrary = lift3 SourcePos@@ -603,10 +619,15 @@         Nothing -> Test.QuickCheck.discard         Just v -> v   where+      denotedExpression :: Expr Void Import+      denotedExpression = Dhall.Core.denote expression+       maybeProp = do           nf <- Control.Spoon.spoon (Dhall.Core.normalize expression)           isNormalized <- Control.Spoon.spoon (Dhall.Core.isNormalized expression)-          return $ isNormalized === (nf == expression)+          -- Dhall.Core.isNormalized ignores 'Note's and other annotations.+          -- So we do the same when checking the result of 'normalize'.+          return $ isNormalized === (nf == denotedExpression)  normalizeWithMIsConsistentWithNormalize :: Expr () Import -> Property normalizeWithMIsConsistentWithNormalize expression =
+ tests/format/dottedFieldsCommentsA.dhall view
@@ -0,0 +1,17 @@+{   {- A -}+    a+    -- B+  . -- C+    b+  . c+    {- D -}+  . d =+      -- E+      x+,   {- F -}+    e+    {- G -}+  . f =+      {- H -}+      { g = y }+}
+ tests/format/dottedFieldsCommentsB.dhall view
@@ -0,0 +1,17 @@+{   {- A -}+    a+    -- B+  . -- C+    b+  . c+    {- D -}+  . d+  = -- E+    x+,   {- F -}+    e+    {- G -}+  . f+  = {- H -}+    { g = y }+}
+ tests/format/punCommentsA.dhall view
@@ -0,0 +1,7 @@+{ {- A -}+  x+  {- B -}+, y =+    {- C -}+    y+}
+ tests/format/punCommentsB.dhall view
@@ -0,0 +1,7 @@+{ {- A -}+  x+  {- B -}+, y =+    {- C -}+    y+}
+ tests/format/recordLitComments0A.dhall view
@@ -0,0 +1,6 @@+{ {- A -}+  x+  {- B -}+  = {- C -}+    T+}
+ tests/format/recordLitComments0B.dhall view
@@ -0,0 +1,6 @@+{ {- A -}+  x+  {- B -}+  = {- C -}+    T+}
+ tests/format/recordLitComments1A.dhall view
@@ -0,0 +1,4 @@+{+--| a comment for y+y = 42+}
+ tests/format/recordLitComments1B.dhall view
@@ -0,0 +1,3 @@+{ --| a comment for y+  y = 42+}
+ tests/format/recordLitMultilineBlockCommentsA.dhall view
@@ -0,0 +1,9 @@+{ {- A+  A -}+  x+  {- B+  B -}+  = {- C+    C -}+    y+}
+ tests/format/recordLitMultilineBlockCommentsB.dhall view
@@ -0,0 +1,9 @@+{ {- A+  A -}+  x+  {- B+  B -}+  = {- C+    C -}+    y+}
+ tests/format/recordTypeCommentsA.dhall view
@@ -0,0 +1,6 @@+{ {- A -}+  a+  {- B -}+  : {- C -}+    A+}
+ tests/format/recordTypeCommentsB.dhall view
@@ -0,0 +1,6 @@+{ {- A -}+  a+  {- B -}+  : {- C -}+    A+}
+ tests/format/usingToMapA.dhall view
@@ -0,0 +1,1 @@+https://httpbin.org/headers using (toMap { TOKEN = "AAAA" }) as Text
+ tests/format/usingToMapB.dhall view
@@ -0,0 +1,1 @@+https://httpbin.org/headers using (toMap { TOKEN = "AAAA" }) as Text