packages feed

dhall 1.36.0 → 1.42.3

raw patch · 1162 files changed

Files

CHANGELOG.md view
@@ -1,3 +1,279 @@+1.42.3++* [Fix the typechecking rule for `Optional` + `with`](https://github.com/dhall-lang/dhall-haskell/pull/2650)+* [Add `*WithIndex` instances for `Map`](https://github.com/dhall-lang/dhall-haskell/pull/2633)+* [`dhall package`: Add support for automatic sub-packags](https://github.com/dhall-lang/dhall-haskell/pull/2639)+* [`dhall to-directory-tree`: Add `binary-file` support](https://github.com/dhall-lang/dhall-haskell/pull/2641)+* [Support GHC 9.12.1](https://github.com/dhall-lang/dhall-haskell/pull/2649)+* [`dhall to-directory-tree`: create parents of files when using fixpoint representation](https://github.com/dhall-lang/dhall-haskell/pull/2653)++1.42.2++* [Supports standard version 23.1.0](https://github.com/dhall-lang/dhall-lang/releases/tag/v23.1.0)+  * [Allow `Natural` and `Integer` literals in binary notation](https://github.com/dhall-lang/dhall-haskell/pull/2540)+* Fix macOS build [[#2561](https://github.com/dhall-lang/dhall-haskell/pull/2561)] / [[#2586](https://github.com/dhall-lang/dhall-haskell/pull/2586)]+* [`dhall to-directory-tree`: Fix support for empty `Map`s](https://github.com/dhall-lang/dhall-haskell/pull/2609)+* [`Dhall.TH`: Improve recompilation checking](https://github.com/dhall-lang/dhall-haskell/pull/2620)+  * `Dhall.TH` utilities now use `addDependentFile` internally so that GHC will recompile if any Dhall dependencies change+* Performance improvements+  * Optimize `Natural/fold`: [[#2585](https://github.com/dhall-lang/dhall-haskell/pull/2585)] / [[#2596](https://github.com/dhall-lang/dhall-haskell/pull/2596)]+  * [Improve `Dhall.Map.traverseWithKey` performance](https://github.com/dhall-lang/dhall-haskell/pull/2589)+    * The fold will now short-circuit if it reaches a fixed point+  * [#2611](https://github.com/dhall-lang/dhall-haskell/pull/2611)+* Fixes and improvements to test suite+  * [#2593](https://github.com/dhall-lang/dhall-haskell/pull/2593)+* Fixes and improvements to haddocks+  * [#2546](https://github.com/dhall-lang/dhall-haskell/pull/2546)+* Fixes and improvements to code formatting+  * [#2608](https://github.com/dhall-lang/dhall-haskell/pull/2608)++1.42.1++* Add several new entrypoints to `Dhall` module [[#2534](https://github.com/dhall-lang/dhall-haskell/pull/2534)] / [[#2544](https://github.com/dhall-lang/dhall-haskell/pull/2544)]+* Build against latest versions of:+  * [`ansi-terminal`](https://github.com/dhall-lang/dhall-haskell/pull/2521)+  * [`optparse-applicative`](https://github.com/dhall-lang/dhall-haskell/pull/2543)+  * [`optparse-generic`](https://github.com/dhall-lang/dhall-haskell/pull/2519)+  * [`lens`](https://github.com/dhall-lang/dhall-haskell/pull/2539)+  * `template-haskell` [[#2532](https://github.com/dhall-lang/dhall-haskell/pull/2532)] / [[#2542](https://github.com/dhall-lang/dhall-haskell/pull/2542)]+  * [`unix-compat`](https://github.com/dhall-lang/dhall-haskell/pull/2532)+1.42.0++* [Supports standard version 23.0.0](https://github.com/dhall-lang/dhall-lang/releases/tag/v23.0.0)+  * [BREAKING CHANGE TO THE API AND LANGUAGE: Language support for `Bytes` literals](https://github.com/dhall-lang/dhall-haskell/pull/2499)+    * This is a breaking change to the API due to adding new `Bytes` and `BytesLiteral` constructors to the `Expr` type+    * This is a breaking change to the language now that `Bytes` is a reserved identifier+  * [BREAKING CHANGE TO THE API AND LANGUAGE: New `{Date,Time,TimeZone}/show` builtins](https://github.com/dhall-lang/dhall-haskell/pull/2493)+    * This is a breaking change to the API due to adding new `{Date,Time,TimeZone}Show` constructors to the `Expr` type+    * This is a breaking change to the language now that `{Date,Time,TimeZone}/show` are not reserved identifiers+* [BREAKING CHANGE: `dhall lint` no longer sorts `let` bindings](https://github.com/dhall-lang/dhall-haskell/pull/2503)+  * This had to be removed because the old behavior was not always correct+  * The old behavior would sometimes change the behavior of a Dhall program or break the program+  * Out of an abundance of caution we're disabling the feature until it can be properly fixed (which is't trivial)+* [BUG FIX: Fix pretty-printing of `Time` literals](https://github.com/dhall-lang/dhall-haskell/pull/2466)+  * The pretty-printer was stripping leading zeros from the fractional component+    of seconds+* [BUG FIX: Fix custom normalizers to work for things other than functions](https://github.com/dhall-lang/dhall-haskell/pull/2464)+  * Before this change you could extend the language with custom functions, but+    not custom values (e.g. `foo = 1`)+* [BUG FIX: Don't URL encode path components](https://github.com/dhall-lang/dhall-haskell/pull/2505)+  * The pretty-printer was URL-encoding path components, which is not correct (according to the standard)+  * URL path components are supposed to be already URL-encoded by the user and left undisturbed by the interpreter (which is now what it correctly does)+* New `dhall package` command: [#2478](https://github.com/dhall-lang/dhall-haskell/pull/2487), [#2508](https://github.com/dhall-lang/dhall-haskell/pull/2508)+  * This command makes it easier to turn a directory full of Dhall expressions+    into a dhall package (e.g. `package.dhall`)+* [Improved `dhall to-directory-tree` subcommand](https://github.com/dhall-lang/dhall-haskell/pull/2437)+  * The `dhall to-directory-tree` subcommand now optionally supports specifying+    metadata for generated paths+  * For a worked example, see: https://github.com/dhall-lang/dhall-haskell/blob/main/dhall/examples/to-directory-tree.dhall+* `dhall freeze --cache --all` is now idempotent: [#2486](https://github.com/dhall-lang/dhall-haskell/pull/2486), [#2500](https://github.com/dhall-lang/dhall-haskell/pull/2500)+  * Before this change a second run would fail due to attempting to resolve+    the `missing` import it would generate+* [New Template Haskell options for adding strictness annotations to generated Haskell types](https://github.com/dhall-lang/dhall-haskell/pull/2504)+* [Template Haskell can now generate higher-kinded Haskell types from higher-kinded Dhall types](https://github.com/dhall-lang/dhall-haskell/pull/2506)+* [New `Dhall.Freeze` utilities for working with custom evaluators](https://github.com/dhall-lang/dhall-haskell/pull/2478)+* [Add `Data` instances for `Import` and various other types](https://github.com/dhall-lang/dhall-haskell/pull/2462)+* [Add `Eq` instances for `InvalidDecoder` and `ExtractError`](https://github.com/dhall-lang/dhall-haskell/pull/2482)++1.41.2++* [BUG FIX: Fix `:hash` REPL command to α-normalize input](https://github.com/dhall-lang/dhall-haskell/pull/2420)+* [Add `{From,To}Dhall` instances for `DayOfWeek`](https://github.com/dhall-lang/dhall-haskell/pull/2413)+* [Add `{From,To}Dhall` instances for `ShortText`](https://github.com/dhall-lang/dhall-haskell/pull/2413)+* Performance improvements+  * [#2423](https://github.com/dhall-lang/dhall-haskell/pull/2423)+* Fixes and improvements to haddocks+  * [#2396](https://github.com/dhall-lang/dhall-haskell/pull/2396)+* Fixes and improvements to test suite+  * [#2342](https://github.com/dhall-lang/dhall-haskell/pull/2382)+  * [#2394](https://github.com/dhall-lang/dhall-haskell/pull/2394)+* Build against newer dependencies+  * [`pretty-simple-4.1`](https://github.com/dhall-lang/dhall-haskell/pull/2408)+  * [`aeson-2.1`](https://github.com/dhall-lang/dhall-haskell/pull/2424)+  * [`vector-0.13`](https://github.com/dhall-lang/dhall-haskell/pull/2427)+  * [`turtle-1.6`](https://github.com/dhall-lang/dhall-haskell/pull/2431)++1.41.1++* [BUG FIX: Don't escape `?` path component when pretty-printing `with` expressions](https://github.com/dhall-lang/dhall-haskell/pull/2392)++1.41.0++* [Support standard version 22.0.0](https://github.com/dhall-lang/dhall-lang/releases/tag/v22.0.0)+  * [Allow `with` expressions to update `Optional` values using `?`](https://github.com/dhall-lang/dhall-haskell/pull/2386)+  * [Add `showConstructor` keyword](https://github.com/dhall-lang/dhall-haskell/pull/2384)+* [BUG FIX: Fix pretty-printing of time zones](https://github.com/dhall-lang/dhall-haskell/pull/2379)+  * Timezones with a negative offset were previously being rendered with two+    leading minus signs instead of one+* [BUG FIX: `dhall freeze --cache` to work with standard version 21.0.0](https://github.com/dhall-lang/dhall-haskell/pull/2350)+  * `dhall freeze` will now use `missing sha256:…` for the first import so that+    the latter import will be tried if the import is not in cache+  * The old behavior is incompatible with standard version 21.0.0 because the+    new behavior of the `?` operator doesn't fall back on hash mismatches+* [BUG FIX: Allow `with` expression to update a field named `Some`](https://github.com/dhall-lang/dhall-haskell/pull/2354)+  * This fixes a discrepancy between the Haskell implementation and the standard+    where the Haskell implementation would not permit+    `{ Some = 0 } with Some = 1 `+* [Fix `dhall {format,lint,freeze}` to preserve leading shebangs](https://github.com/dhall-lang/dhall-haskell/pull/2364)+* [Add `FromDhall` instances for `Int{8,16,32,64}`](https://github.com/dhall-lang/dhall-haskell/pull/2349)++1.40.2++* [Supports standard version 21.1.0](https://github.com/dhall-lang/dhall-haskell/pull/2236)+    * [The interpreter now supports customizing headers using a `headers.dhall`+      configuration file](https://github.com/dhall-lang/dhall-haskell/pull/2236)+    * [Generalize grammar for certain annotations](https://github.com/dhall-lang/dhall-haskell/pull/2320)+    * [Add support for a trailing line comment without a newline](https://github.com/dhall-lang/dhall-haskell/pull/2309)+* [BUG FIX: `dhall repl` no longer ignores type annotations on `:let` commands](https://github.com/dhall-lang/dhall-haskell/pull/2297)+    * Before this fix, `:let x : T = 3` would ignore the `: T` type annotation+* [BUG FIX: Don't accept a bar after an empty union](https://github.com/dhall-lang/dhall-haskell/pull/2338)+    * Before this fix, the interpreter would accept something like `<>|`, which+      is not valid according to the standard grammar+* New `FromDhall`/`ToDhall` instances for `Day`/`TimeOfDay`/`TimeZone` [#2294](https://github.com/dhall-lang/dhall-haskell/pull/2294) [#2300](https://github.com/dhall-lang/dhall-haskell/pull/2300)+    * These types correspond to the recent temporal literals added to the+      language+* [New `subExpressionsWith` `Traversal`](https://github.com/dhall-lang/dhall-haskell/pull/2302)+* [Add Template Haskell support for modifying field names in generated Haskell+  types](https://github.com/dhall-lang/dhall-haskell/pull/2285)+    * This adds a new `makeHaskellTypesWith` utility with takes a+      `GenerateOptions` function argument for customizing the code-generation+      logic+    * This comes in handy when Dhall fields have names are reserved keywords in+      Haskell code.  You can now transform the Haskell field names to avoid+      collisions+* [Support GHC 9.2](https://github.com/dhall-lang/dhall-haskell/pull/2328)+* Fixes and improvements to documentation+    * [#2290](https://github.com/dhall-lang/dhall-haskell/pull/2290)+* Fixes and improvements to error messages+    * [#2303](https://github.com/dhall-lang/dhall-haskell/pull/2303)++1.40.1++* [BUG FIX: Fix equivalence check for `Date` / `Time` / `TimeZone`](https://github.com/dhall-lang/dhall-haskell/pull/2291)+    * This fixes a serious bug in the recently introduced support for temporal+      literals where they would fail to type-check when given a correct type+      annotation or when they were checked against an existing type+    * For example, `00:00:00 : Time` was failing to type-check++1.40.0++* [Almost supports version 20.2.0 of the standard](https://github.com/dhall-lang/dhall-lang/releases/tag/v20.2.0)+    * The main thing that is missing is support for the `headers.dhall` file+    * [BREAKING CHANGE TO THE LANGUAGE: Add support for `Date` / `Time` / `TimeZone` ](https://github.com/dhall-lang/dhall-haskell/pull/2247)+        * This is a breaking change because `Date`, `Time`, and `TimeZone` are+          now reserved identifiers+    * [Improved fallback behavior for `?`](https://github.com/dhall-lang/dhall-haskell/pull/2203)+* [BREAKING CHANGE TO THE LANGUAGE: Require whitespace before `with`](https://github.com/dhall-lang/dhall-haskell/pull/2213)+    * The parser now requires whitespace before the `with` keyword, which brings+      the Haskell implementation into closer compliance with the standard+    * In practice this is a technically breaking change which will not affect+      most programs+* [New `FromDhall` instances for `Predicate`, `Equivalence`, and `Op`](https://github.com/dhall-lang/dhall-haskell/pull/2278)+* [`dhall lint` will now sort `let` bindings with imports](https://github.com/dhall-lang/dhall-haskell/pull/2205)+    * `dhall lint` now reorders `let` bindings to move imports to the top so+      long as doing so does not change the behavior of the program+* Fixes and improvements to code formatting+    * [#2280](https://github.com/dhall-lang/dhall-haskell/pull/2280)+* Fixes and improvements to error messages+    * [#2244](https://github.com/dhall-lang/dhall-haskell/pull/2244)+    * [#2238](https://github.com/dhall-lang/dhall-haskell/pull/2238)++1.39.0++* [Supports version 20.2.0 of the standard](https://github.com/dhall-lang/dhall-lang/releases/tag/v20.2.0)+    * [Add support for Unix shebangs](https://github.com/dhall-lang/dhall-haskell/pull/2175)+* [BREAKING CHANGE TO THE API: `dhall {format,freeze,lint}` now accept multiple+  files](https://github.com/dhall-lang/dhall-haskell/pull/2169)+    * The `--inplace` flag is no longer necessary and you can now specify+      multiple files to update in place on the command line, like+      `dhall format foo.dhall bar.dhall`+    * The `--inplace` flag is still accepted, but does nothing, and will emit a+      warning+    * This is a breaking change to the API for formatting/freezing/linting files+      because now you can specify multiple inputs instead of one input+* [BREAKING CHANGE: Pre-6.0.0 hashes are no longer supported](https://github.com/dhall-lang/dhall-haskell/pull/2190)+    * The interpreter no longer provides backwards compatibility for integrity+      checks computed before standard version 6.0.0+    * This is a breaking change to the API of the `Dhall.Binary` module, where+      certain utilities are no longer parameterized on a `StandardVersion`+    * This is also a breaking change to any Dhall code that depended on these+      really old integrity checks+* [BUG FIX: Formatting `≡` now correctly preserves the original character set](https://github.com/dhall-lang/dhall-haskell/pull/2176)+* [BUG FIX: Don't panic on `Text/replace ""`](https://github.com/dhall-lang/dhall-haskell/pull/2184)+* [Quasiquotation support for Dhall](https://github.com/dhall-lang/dhall-haskell/pull/2198)+    * You can now convert a Dhall expression to the corresponding syntax tree+      using a quasiquoter like this: `[dhall| \x -> x + 2 ]`+* [New `Dhall.Marshal.{Encode,Decode}` modules](https://github.com/dhall-lang/dhall-haskell/pull/2193)+    * These modules split up the `Dhall` module into two smaller modules for+      encoding and decoding logic, respectively+    * The `Dhall` module still re-exports the same functionality as before, so+      this is not a breaking change+* [Support GHC 9.0.1](https://github.com/dhall-lang/dhall-haskell/pull/2154)+* Fixes and improvements to code formatting+    * [Improve pretty-printing of `sha256`](https://github.com/dhall-lang/dhall-haskell/pull/2189)++1.38.1++* [Add `INLINABLE` annotations in more places](https://github.com/dhall-lang/dhall-haskell/pull/2164)+    * This may improve performance by enabling more specializations+* [Fix `hashable`-related test failures](https://github.com/dhall-lang/dhall-haskell/pull/2152)+* [Fix support for GHC 8.4.4](https://github.com/dhall-lang/dhall-haskell/pull/2143)+    * … by using `GeneralizedNewtypeDeriving` (with a `z`)+* [Allow doctest-0.18](https://github.com/dhall-lang/dhall-haskell/pull/2148)+* [Allow bytestring-0.11](https://github.com/dhall-lang/dhall-haskell/pull/2144)++1.38.0++* [BREAKING CHANGE: Detect preferred character set from input](https://github.com/dhall-lang/dhall-haskell/pull/2108)+    * `dhall format` will now preserve the character set of the formatted file+      by default.  In other words, if the file uses ASCII punctuation then+      `dhall format` will format the file using ASCII punctuation.+    * If the file contains both ASCII and Unicode punctuation it will prefer+      Unicode by default+    * This is a breaking change because the `Lam` / `Pi` / `Combine` /+      `CombineTypes`, and `Prefer` constructors now take an additional argument+      to record which character set was used+* [BUG FIX: Fix CORS compliance check](https://github.com/dhall-lang/dhall-haskell/pull/2121)+    * Previous versions were not correctly enforcing CORS compliance+    * This implies that some imports that would have worked previously by+      accident will now fail; specifically: an import from one domain+      transitively importing something from another domain that has not opted+      into CORS+* [Add `ToDhall (Fix f)` instance](https://github.com/dhall-lang/dhall-haskell/pull/2122)+* Fixes and improvements to error messages+    * [#2130](https://github.com/dhall-lang/dhall-haskell/pull/2130)++1.37.1++* [Fix performance regression for `with` expressions](https://github.com/dhall-lang/dhall-haskell/pull/2112)++1.37.0++* [Supports version 20.0.0 of the standard](https://github.com/dhall-lang/dhall-lang/releases/tag/v20.0.0)+    * [Implement revised `Text/replace` β-normalization](https://github.com/dhall-lang/dhall-haskell/pull/2072)+    * [Allow `Text/replace ""` to support an abstract haystack](https://github.com/dhall-lang/dhall-haskell/pull/2084)+    * [Support `if` expressions returning a type or kind](https://github.com/dhall-lang/dhall-haskell/pull/2080)+* BREAKING CHANGE TO THE API: [Improve error message for duplicate projection label](https://github.com/dhall-lang/dhall-haskell/pull/2097)+    * This also makes the implementation more standards-compliant, by treating+      a duplicate label as a type error instead of a parse error+    * This is a breaking change since the `Project` constructor now stores a+      `[Text]` instead of `Set Text`+* [Add `--cache` flag to `dhall hash`](https://github.com/dhall-lang/dhall-haskell/pull/2093)+    * This flag adds the hashed expression to the cache when enabled+* [Deprecate `Inject` / `Interpret`](https://github.com/dhall-lang/dhall-haskell/pull/2099)+    * You should instead use `ToDhall` / `FromDhall`, respectively+* Fixes and improvements to the haddocks:+    * [#2098](https://github.com/dhall-lang/dhall-haskell/pull/2098)+    * [#2100](https://github.com/dhall-lang/dhall-haskell/pull/2100)+* Fixes and improvements to error messages:+    * [#2082](https://github.com/dhall-lang/dhall-haskell/pull/2082)+    * [#2095](https://github.com/dhall-lang/dhall-haskell/pull/2095)+* Fixes and improvements to the parser:+    * [#2083](https://github.com/dhall-lang/dhall-haskell/pull/2089)+* Fixes and improvements to the pretty printer:+    * [#2083](https://github.com/dhall-lang/dhall-haskell/pull/2083)+    * [#2101](https://github.com/dhall-lang/dhall-haskell/pull/2101)+ 1.36.0  * [Supports version 19.0.0 of the standard](https://github.com/dhall-lang/dhall-lang/releases/tag/v19.0.0)@@ -114,6 +390,12 @@     * If you really don't want to handle the new error-related wrapper, you can       get the old behavior using a partial pattern match (which will be partial,       still an improvement over the previous behavior, which was hanging)+* BREAKING CHANGE: [Records can no longer contain attributes named after language keywords](https://github.com/dhall-lang/dhall-haskell/pull/1801)+    * This is a bugfix, because the language standard disallows using+      keywords as record labels. However, some users were relying on+      this bug.+    * If you need to use a keyword as a record label, enclose it in backticks:+      ``{ `assert` = 1 }``. * [Fix invalid cache entries](https://github.com/dhall-lang/dhall-haskell/pull/1793)     * The interpreter will now correct cached expressions that are incorrect       and warn you when this happens@@ -850,7 +1132,7 @@     * This allows the `dhall` package to be built without using       `TemplateHaskell`     * See: https://github.com/dhall-lang/dhall-haskell/pull/928-* Increase lines of context for error messages +* Increase lines of context for error messages     * Error messages now provide at least 20 lines of context instead of 3       before truncating large expressions     * See: https://github.com/dhall-lang/dhall-haskell/pull/916@@ -1233,7 +1515,7 @@       expression     * You can pin the new hashes by supplying the `--protocol-version 1.0`       option on the command line until you need support for newer language-      features +      features     * This also includes a breaking change to `ImportType` in the API * BREAKING CHANGE TO THE LANGUAGE: Disallow combining records of terms and   types
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2020 Gabriel Gonzalez+Copyright (c) 2020 Gabriella Gonzalez All rights reserved.  Redistribution and use in source and binary forms, with or without
benchmark/deep-nested-large-record/Main.hs view
@@ -1,14 +1,13 @@ {-# LANGUAGE OverloadedStrings #-} module Main (main) where -import Data.Void (Void)-import Gauge (defaultMain)+import Data.Void        (Void)+import Test.Tasty.Bench  import qualified Data.Sequence   as Seq import qualified Dhall.Core      as Core import qualified Dhall.Import    as Import import qualified Dhall.TypeCheck as TypeCheck-import qualified Gauge  dhallPreludeImport :: Core.Import dhallPreludeImport = Core.Import@@ -22,8 +21,8 @@     }   } -issue412 :: Core.Expr s Void -> Gauge.Benchmarkable-issue412 prelude = Gauge.whnf TypeCheck.typeOf expr+issue412 :: Core.Expr s Void -> Benchmarkable+issue412 prelude = whnf TypeCheck.typeOf expr   where     expr       = Core.Let (Core.Binding Nothing "prelude" Nothing Nothing Nothing prelude)@@ -34,8 +33,8 @@     little = Core.makeFieldSelection "little"     foo = Core.makeFieldSelection "Foo" -unionPerformance :: Core.Expr s Void -> Gauge.Benchmarkable-unionPerformance prelude = Gauge.whnf TypeCheck.typeOf expr+unionPerformance :: Core.Expr s Void -> Benchmarkable+unionPerformance prelude = whnf TypeCheck.typeOf expr   where     expr =         Core.Let@@ -54,7 +53,7 @@                         Nothing                         (prelude `Core.Field` types `Core.Field` big)                     )-                    (Core.Prefer Core.PreferFromSource "big" "big")+                    (Core.Prefer mempty Core.PreferFromSource "big" "big")                 )             )             "x"@@ -64,10 +63,10 @@ main :: IO () main =   defaultMain-    [ Gauge.env prelude $ \p ->-      Gauge.bgroup "Prelude"-        [ Gauge.bench "issue 412" (issue412 p)-        , Gauge.bench "union performance" (unionPerformance p)+    [ env prelude $ \p ->+      bgroup "Prelude"+        [ bench "issue 412" (issue412 p)+        , bench "union performance" (unionPerformance p)         ]     ]   where prelude = Import.load (Core.Embed dhallPreludeImport)
− benchmark/examples/cpkg.dhall

file too large to diff

− benchmark/examples/issue108.dhall
@@ -1,63 +0,0 @@-λ ( xs : List { cores : Natural , host : Text , key : Text , mandatoryFeatures :-List Text , platforms : List < AArch64_Linux : {} | ARMv5tel_Linux : {} |-ARMv7l_Linux : {} | I686_Cygwin : {} | I686_Linux : {} | MIPS64el_Linux : {} |-PowerPC_Linux : {} | X86_64_Cygwin : {} | X86_64_Darwin : {} | X86_64_FreeBSD :-{} | X86_64_Linux : {} | X86_64_Solaris : {} > , speedFactor : Natural ,-supportedFeatures : List Text , user : Optional Text } )→ List/fold { cores :-Natural , host : Text , key : Text , mandatoryFeatures : List Text , platforms :-List < AArch64_Linux : {} | ARMv5tel_Linux : {} | ARMv7l_Linux : {} |-I686_Cygwin : {} | I686_Linux : {} | MIPS64el_Linux : {} | PowerPC_Linux : {} |-X86_64_Cygwin : {} | X86_64_Darwin : {} | X86_64_FreeBSD : {} | X86_64_Linux :-{} | X86_64_Solaris : {} > , speedFactor : Natural , supportedFeatures : List-Text , user : Optional Text } xs Text ( λ ( x : { cores : Natural , host : Text-, key : Text , mandatoryFeatures : List Text , platforms : List < AArch64_Linux-: {} | ARMv5tel_Linux : {} | ARMv7l_Linux : {} | I686_Cygwin : {} | I686_Linux :-{} | MIPS64el_Linux : {} | PowerPC_Linux : {} | X86_64_Cygwin : {} |-X86_64_Darwin : {} | X86_64_FreeBSD : {} | X86_64_Linux : {} | X86_64_Solaris :-{} > , speedFactor : Natural , supportedFeatures : List Text , user : Optional-Text } ) → λ(y : Text) →-merge { None = x.host, Some = λ(user : Text) → "${user}@${x.host}" } x.user-++ " " ++ ( merge { Empty = λ(_ : {}) → "",-NonEmpty = λ(result : Text) → result } ( List/fold < AArch64_Linux : {} |-ARMv5tel_Linux : {} | ARMv7l_Linux : {} | I686_Cygwin : {} | I686_Linux : {} |-MIPS64el_Linux : {} | PowerPC_Linux : {} | X86_64_Cygwin : {} | X86_64_Darwin :-{} | X86_64_FreeBSD : {} | X86_64_Linux : {} | X86_64_Solaris : {} > x.platforms-< Empty : {} | NonEmpty : Text > ( λ ( element : < AArch64_Linux : {} |-ARMv5tel_Linux : {} | ARMv7l_Linux : {} | I686_Cygwin : {} | I686_Linux : {} |-MIPS64el_Linux : {} | PowerPC_Linux : {} | X86_64_Cygwin : {} | X86_64_Darwin :-{} | X86_64_FreeBSD : {} | X86_64_Linux : {} | X86_64_Solaris : {} > ) →-λ(status : < Empty : {} | NonEmpty : Text >) → merge { Empty = λ(_ : {}) → <-NonEmpty : Text | Empty : {} >.NonEmpty ( merge { AArch64_Linux = λ(_ : {}) →-"aarch64-linux" , ARMv5tel_Linux = λ(_ : {}) → "armv5tel-linux" , ARMv7l_Linux =-λ(_ : {}) → "armv7l-linux" , I686_Cygwin = λ(_ : {}) → "i686-cygwin" ,-I686_Linux = λ(_ : {}) → "i686-linux" , MIPS64el_Linux = λ(_ : {}) →-"mips64el-linux" , PowerPC_Linux = λ(_ : {}) → "powerpc-linux" , X86_64_Cygwin =-λ(_ : {}) → "x86_64-cygwin" , X86_64_Darwin = λ(_ : {}) → "x86_64-darwin" ,-X86_64_FreeBSD = λ(_ : {}) → "x86_64-freebsd" , X86_64_Linux = λ(_ : {}) →-"x86_64-linux" , X86_64_Solaris = λ(_ : {}) → "x86_64-solaris" } element ) ,-NonEmpty = λ(result : Text) → < NonEmpty : Text | Empty : {} >.NonEmpty ( (-merge { AArch64_Linux = λ(_ : {}) → "aarch64-linux" , ARMv5tel_Linux = λ(_ : {})-→ "armv5tel-linux" , ARMv7l_Linux = λ(_ : {}) → "armv7l-linux" , I686_Cygwin =-λ(_ : {}) → "i686-cygwin" , I686_Linux = λ(_ : {}) → "i686-linux" ,-MIPS64el_Linux = λ(_ : {}) → "mips64el-linux" , PowerPC_Linux = λ(_ : {}) →-"powerpc-linux" , X86_64_Cygwin = λ(_ : {}) → "x86_64-cygwin" , X86_64_Darwin =-λ(_ : {}) → "x86_64-darwin" , X86_64_FreeBSD = λ(_ : {}) → "x86_64-freebsd" ,-X86_64_Linux = λ(_ : {}) → "x86_64-linux" , X86_64_Solaris = λ(_ : {}) →-"x86_64-solaris" } element ) ++ "," ++ result ) } status : < Empty : {} |-NonEmpty : Text > ) (< Empty : {} | NonEmpty : Text >.Empty {=}) ) : Text ) ++-" " ++ x.key ++ " " ++ Integer/show (Natural/toInteger x.cores) ++ " " ++-Integer/show (Natural/toInteger x.speedFactor) ++ " " ++ ( merge { Empty = λ(_ :-{}) → "", NonEmpty = λ(result : Text) → result } ( List/fold Text-x.supportedFeatures < Empty : {} | NonEmpty : Text > ( λ(element : Text) →-λ(status : < Empty : {} | NonEmpty : Text >) → merge { Empty = λ(_ : {}) → <-NonEmpty : Text | Empty : {} >.NonEmpty element , NonEmpty = λ(result : Text) →-< NonEmpty : Text | Empty : {} >.NonEmpty (element ++ "," ++ result) } status :-< Empty : {} | NonEmpty : Text > ) (< Empty : {} | NonEmpty : Text >.Empty {=})-) : Text ) ++ " " ++ ( merge { Empty = λ(_ : {}) → "", NonEmpty = λ(result :-Text) → result } ( List/fold Text x.mandatoryFeatures < Empty : {} | NonEmpty :-Text > ( λ(element : Text) → λ(status : < Empty : {} | NonEmpty : Text >) →-merge { Empty = λ(_ : {}) → < NonEmpty : Text | Empty : {} >.NonEmpty element ,-NonEmpty = λ(result : Text) → < NonEmpty : Text | Empty : {} >.NonEmpty-(element ++ "," ++ result) } status : < Empty : {} | NonEmpty : Text > ) (<-Empty : {} | NonEmpty : Text->.Empty {=}) ) : Text ) ++ "\n" ++ y ) ""
− benchmark/examples/normalize/ChurchEval.dhall
@@ -1,22 +0,0 @@--let Nat = ∀(N : Type) → (N → N) → N → N-let n2  = λ(N : Type) → λ(s : N → N) → λ(z : N) → s (s z)-let n5  = λ(N : Type) → λ(s : N → N) → λ(z : N) → s (s (s (s (s z))))--let mul =-  λ(a : Nat) → λ(b : Nat) → λ(N : Type) → λ(s : N → N) → λ(z : N) → a N (b N s) z--let add =-  λ(a : Nat) → λ(b : Nat) → λ(N : Type) → λ(s : N → N) → λ(z : N) → a N s (b N s z)--let n10   = mul n2 n5-let n100  = mul n10 n10-let n1k   = mul n10 n100-let n10k  = mul n100 n100-let n100k = mul n10 n10k-let n1M   = mul n10k n100-let n5M   = mul n1M n5-let n10M  = mul n1M n10-let n20M  = mul n10M n2--in n1M Natural (λ (x:Natural) → x + 1) 0
− benchmark/examples/normalize/FunCompose.dhall
@@ -1,18 +0,0 @@--let compose-    : ∀(a : Type) → ∀(b : Type) → ∀(c : Type) → (a → b) → (b → c) → a → c-    =   λ(A : Type)-      → λ(B : Type)-      → λ(C : Type)-      → λ(f : A → B)-      → λ(g : B → C)-      → λ(x : A)-      → g (f x)--let composeN : ∀ (a : Type) → Natural → (a → a) → a → a-    = λ (a : Type)-	→ λ (n : Natural)-	→ λ (f : a → a)-	→ Natural/fold n (a → a) (compose a a a f) (λ (x : a) → x)--in composeN Natural 100000 (λ (x : Natural) → x + 1) 0
− benchmark/examples/normalize/ListBench.dhall
@@ -1,75 +0,0 @@--let iterate-    =   λ(n : Natural)-      → λ(a : Type)-      → λ(f : a → a)-      → λ(x : a)-      → List/build-        a-        (   λ(list : Type)-          → λ(cons : a → list → list)-          → List/fold-            { index : Natural, value : {} }-            ( List/indexed-              {}-              ( List/build-                {}-                (   λ(list : Type)-                  → λ(cons : {} → list → list)-                  → Natural/fold n list (cons {=})-                )-              )-            )-            list-            (   λ(y : { index : Natural, value : {} })-              → cons (Natural/fold y.index a f x)-            )-        )--let countTo =-  λ (x : Natural)-  → iterate x Natural (λ (x : Natural) → x + 1) 0--let sum =-  λ (xs : List Natural)-  → List/fold Natural xs Natural (λ (x : Natural) → λ (acc : Natural) → x + acc) 0---let map-        : ∀(a : Type) → ∀(b : Type) → (a → b) → List a → List b-        =   λ(a : Type)-          → λ(b : Type)-          → λ(f : a → b)-          → λ(xs : List a)-          → List/build-            b-            (   λ(list : Type)-              → λ(cons : b → list → list)-              → List/fold a xs list (λ(x : a) → cons (f x))-            )--let any-        : ∀(a : Type) → (a → Bool) → List a → Bool-        =   λ(a : Type)-          → λ(f : a → Bool)-          → λ(xs : List a)-          → List/fold a xs Bool (λ(x : a) → λ(r : Bool) → f x || r) False--let filter-        : ∀(a : Type) → (a → Bool) → List a → List a-        =   λ(a : Type)-          → λ(f : a → Bool)-          → λ(xs : List a)-          → List/build-            a-            (   λ(list : Type)-              → λ(cons : a → list → list)-              → List/fold-                a-                xs-                list-                (λ(x : a) → λ(xs : list) → if f x then cons x xs else xs)-            )--in sum (filter Natural Natural/even-     (map Natural Natural (λ(x:Natural) → x + 10) (countTo 1000)))
− benchmark/examples/normalize/ListBenchAlt.dhall
@@ -1,45 +0,0 @@--let iterate =-    λ(n : Natural)-  → λ(a : Type)-  → λ(f : a → a)-  → λ(x : a)-  → (Natural/fold n-      (a → List a → {fst:a, snd:List a})-	  (λ (hyp : a → List a → {fst:a, snd:List a}) →-	   λ (x : a) → λ (xs : List a)-	   → let tup = hyp x xs-	     in {fst = f (tup.fst), snd = tup.snd # [tup.fst]})-	  (λ (x : a) → λ (xs : List a) → {fst=x, snd=xs})-	  x ([] : List a)).snd--let countTo =-  λ (x : Natural)-  → iterate x Natural (λ (x : Natural) → x + 1) 0--let sum =-  λ (xs : List Natural)-  → List/fold Natural xs Natural (λ (x : Natural) → λ (acc : Natural) → x + acc) 0--let map-  =   λ(a : Type)-    → λ(b : Type)-    → λ(f : a → b)-    → λ(xs : List a)-	→ List/fold a xs (List b) (λ (x : a) → λ (xs : List b) → [f x] # xs) ([] : List b)--let any-  =   λ(a : Type)-        → λ(f : a → Bool)-        → λ(xs : List a)-        → List/fold a xs Bool (λ(x : a) → λ(r : Bool) → f x || r) False--let filter-  =   λ(a : Type)-    → λ(f : a → Bool)-    → λ(xs : List a)-	→ List/fold a xs (List a)-	    (λ (x : a) → λ (xs : List a) → if f x then [x] # xs else xs) ([] : List a)--in sum (filter Natural Natural/even-     (map Natural Natural (λ(x:Natural) → x + 10) (countTo 1000)))
benchmark/parser/Main.hs view
@@ -1,54 +1,54 @@+{-# LANGUAGE BangPatterns      #-} {-# LANGUAGE OverloadedStrings #-}  module Main where  import Control.Exception (throw) import Control.Monad     (forM)-import Data.Map          (Map, foldrWithKey, singleton, unions)+import Data.Map          (Map)+import Data.Text         (Text) import Data.Void         (Void)-import Gauge             (bench, bgroup, defaultMain, env, nf, whnf)--import System.Directory+import Test.Tasty.Bench  import qualified Data.ByteString.Lazy-import qualified Data.Text            as T-import qualified Data.Text.IO         as TIO+import qualified Data.Map             as Map+import qualified Data.Text            as Text+import qualified Data.Text.IO import qualified Dhall.Binary import qualified Dhall.Core           as Dhall import qualified Dhall.Parser         as Dhall-import qualified Gauge+import qualified System.Directory     as Directory -type PreludeFiles = Map FilePath T.Text+type PreludeFiles = Map FilePath Text  loadPreludeFiles :: IO PreludeFiles loadPreludeFiles = loadDirectory "./dhall-lang/Prelude"     where         loadDirectory :: FilePath -> IO PreludeFiles         loadDirectory dir =-            withCurrentDirectory dir $ do-                files <- getCurrentDirectory >>= listDirectory+            Directory.withCurrentDirectory dir $ do+                files <- Directory.getCurrentDirectory >>= Directory.listDirectory                 results <- forM files $ \file -> do-                    file' <- makeAbsolute file-                    doesExist <- doesFileExist file'+                    file' <- Directory.makeAbsolute file+                    doesExist <- Directory.doesFileExist file'                     if doesExist                        then loadFile file'                        else loadDirectory file'-                pure $ unions results+                pure $ Map.unions results          loadFile :: FilePath -> IO PreludeFiles-        loadFile path = singleton path <$> TIO.readFile path+        loadFile path = Map.singleton path <$> Data.Text.IO.readFile path -benchParser :: PreludeFiles -> Gauge.Benchmark+benchParser :: PreludeFiles -> Benchmark benchParser =       bgroup "exprFromText"-    . foldrWithKey (\name expr -> (benchExprFromText name expr :)) []+    . Map.foldrWithKey (\name expr -> (benchExprFromText name expr :)) [] -benchExprFromText :: String -> T.Text -> Gauge.Benchmark-benchExprFromText name expr =+benchExprFromText :: String -> Text -> Benchmark+benchExprFromText name !expr =     bench name $ whnf (Dhall.exprFromText "(input)") expr -benchExprFromBytes-    :: String -> Data.ByteString.Lazy.ByteString -> Gauge.Benchmark+benchExprFromBytes :: String -> Data.ByteString.Lazy.ByteString -> Benchmark benchExprFromBytes name bs = bench name (nf f bs)   where     f bytes =@@ -56,8 +56,8 @@             Left  exception  -> error (show exception)             Right expression -> expression :: Dhall.Expr Void Dhall.Import -benchNfExprFromText :: String -> T.Text -> Gauge.Benchmark-benchNfExprFromText name expr =+benchNfExprFromText :: String -> Text -> Benchmark+benchNfExprFromText name !expr =     bench name $ nf (either throw id . Dhall.exprFromText "(input)") expr  main :: IO ()@@ -71,20 +71,21 @@                 ]         , env kubernetesExample $             benchExprFromBytes "Kubernetes/Binary"-        , benchExprFromText "Long variable names" (T.replicate 1000000 "x")-        , benchExprFromText "Large number of function arguments" (T.replicate 10000 "x ")-        , benchExprFromText "Long double-quoted strings" ("\"" <> T.replicate 1000000 "x" <> "\"")-        , benchExprFromText "Long single-quoted strings" ("''" <> T.replicate 1000000 "x" <> "''")-        , benchExprFromText "Whitespace" (T.replicate 1000000 " " <> "x")-        , benchExprFromText "Line comment" ("x -- " <> T.replicate 1000000 " ")-        , benchExprFromText "Block comment" ("x {- " <> T.replicate 1000000 " " <> "-}")+        , benchExprFromText "Long variable names" (Text.replicate 1000000 "x")+        , benchExprFromText "Large number of function arguments" (Text.replicate 10000 "x ")+        , benchExprFromText "Long double-quoted strings" ("\"" <> Text.replicate 1000000 "x" <> "\"")+        , benchExprFromText "Long single-quoted strings" ("''" <> Text.replicate 1000000 "x" <> "''")+        , benchExprFromText "Whitespace" (Text.replicate 1000000 " " <> "x")+        , benchExprFromText "Line comment" ("x -- " <> Text.replicate 1000000 " ")+        , benchExprFromText "Block comment" ("x {- " <> Text.replicate 1000000 " " <> "-}")         , benchExprFromText "Deeply nested parentheses" "((((((((((((((((x))))))))))))))))"         , benchParser prelude         , env cpkgExample $             benchNfExprFromText "CPkg/Text"         ]-    where cpkgExample = TIO.readFile "benchmark/examples/cpkg.dhall"-          issue108Text = TIO.readFile "benchmark/examples/issue108.dhall"-          issue108Bytes = Data.ByteString.Lazy.readFile "benchmark/examples/issue108.dhall.bin"-          issues = (,) <$> issue108Text <*> issue108Bytes-          kubernetesExample = Data.ByteString.Lazy.readFile "benchmark/examples/kubernetes.dhall.bin"+    where+        cpkgExample = Data.Text.IO.readFile "benchmark/parser/examples/cpkg.dhall"+        issue108Text = Data.Text.IO.readFile "benchmark/parser/examples/issue108.dhall"+        issue108Bytes = Data.ByteString.Lazy.readFile "benchmark/parser/examples/issue108.dhallb"+        issues = (,) <$> issue108Text <*> issue108Bytes+        kubernetesExample = Data.ByteString.Lazy.readFile "benchmark/parser/examples/kubernetes.dhallb"
+ benchmark/parser/examples/cpkg.dhall view

file too large to diff

+ benchmark/parser/examples/issue108.dhall view
@@ -0,0 +1,63 @@+λ ( xs : List { cores : Natural , host : Text , key : Text , mandatoryFeatures :+List Text , platforms : List < AArch64_Linux : {} | ARMv5tel_Linux : {} |+ARMv7l_Linux : {} | I686_Cygwin : {} | I686_Linux : {} | MIPS64el_Linux : {} |+PowerPC_Linux : {} | X86_64_Cygwin : {} | X86_64_Darwin : {} | X86_64_FreeBSD :+{} | X86_64_Linux : {} | X86_64_Solaris : {} > , speedFactor : Natural ,+supportedFeatures : List Text , user : Optional Text } )→ List/fold { cores :+Natural , host : Text , key : Text , mandatoryFeatures : List Text , platforms :+List < AArch64_Linux : {} | ARMv5tel_Linux : {} | ARMv7l_Linux : {} |+I686_Cygwin : {} | I686_Linux : {} | MIPS64el_Linux : {} | PowerPC_Linux : {} |+X86_64_Cygwin : {} | X86_64_Darwin : {} | X86_64_FreeBSD : {} | X86_64_Linux :+{} | X86_64_Solaris : {} > , speedFactor : Natural , supportedFeatures : List+Text , user : Optional Text } xs Text ( λ ( x : { cores : Natural , host : Text+, key : Text , mandatoryFeatures : List Text , platforms : List < AArch64_Linux+: {} | ARMv5tel_Linux : {} | ARMv7l_Linux : {} | I686_Cygwin : {} | I686_Linux :+{} | MIPS64el_Linux : {} | PowerPC_Linux : {} | X86_64_Cygwin : {} |+X86_64_Darwin : {} | X86_64_FreeBSD : {} | X86_64_Linux : {} | X86_64_Solaris :+{} > , speedFactor : Natural , supportedFeatures : List Text , user : Optional+Text } ) → λ(y : Text) →+merge { None = x.host, Some = λ(user : Text) → "${user}@${x.host}" } x.user+++ " " ++ ( merge { Empty = λ(_ : {}) → "",+NonEmpty = λ(result : Text) → result } ( List/fold < AArch64_Linux : {} |+ARMv5tel_Linux : {} | ARMv7l_Linux : {} | I686_Cygwin : {} | I686_Linux : {} |+MIPS64el_Linux : {} | PowerPC_Linux : {} | X86_64_Cygwin : {} | X86_64_Darwin :+{} | X86_64_FreeBSD : {} | X86_64_Linux : {} | X86_64_Solaris : {} > x.platforms+< Empty : {} | NonEmpty : Text > ( λ ( element : < AArch64_Linux : {} |+ARMv5tel_Linux : {} | ARMv7l_Linux : {} | I686_Cygwin : {} | I686_Linux : {} |+MIPS64el_Linux : {} | PowerPC_Linux : {} | X86_64_Cygwin : {} | X86_64_Darwin :+{} | X86_64_FreeBSD : {} | X86_64_Linux : {} | X86_64_Solaris : {} > ) →+λ(status : < Empty : {} | NonEmpty : Text >) → merge { Empty = λ(_ : {}) → <+NonEmpty : Text | Empty : {} >.NonEmpty ( merge { AArch64_Linux = λ(_ : {}) →+"aarch64-linux" , ARMv5tel_Linux = λ(_ : {}) → "armv5tel-linux" , ARMv7l_Linux =+λ(_ : {}) → "armv7l-linux" , I686_Cygwin = λ(_ : {}) → "i686-cygwin" ,+I686_Linux = λ(_ : {}) → "i686-linux" , MIPS64el_Linux = λ(_ : {}) →+"mips64el-linux" , PowerPC_Linux = λ(_ : {}) → "powerpc-linux" , X86_64_Cygwin =+λ(_ : {}) → "x86_64-cygwin" , X86_64_Darwin = λ(_ : {}) → "x86_64-darwin" ,+X86_64_FreeBSD = λ(_ : {}) → "x86_64-freebsd" , X86_64_Linux = λ(_ : {}) →+"x86_64-linux" , X86_64_Solaris = λ(_ : {}) → "x86_64-solaris" } element ) ,+NonEmpty = λ(result : Text) → < NonEmpty : Text | Empty : {} >.NonEmpty ( (+merge { AArch64_Linux = λ(_ : {}) → "aarch64-linux" , ARMv5tel_Linux = λ(_ : {})+→ "armv5tel-linux" , ARMv7l_Linux = λ(_ : {}) → "armv7l-linux" , I686_Cygwin =+λ(_ : {}) → "i686-cygwin" , I686_Linux = λ(_ : {}) → "i686-linux" ,+MIPS64el_Linux = λ(_ : {}) → "mips64el-linux" , PowerPC_Linux = λ(_ : {}) →+"powerpc-linux" , X86_64_Cygwin = λ(_ : {}) → "x86_64-cygwin" , X86_64_Darwin =+λ(_ : {}) → "x86_64-darwin" , X86_64_FreeBSD = λ(_ : {}) → "x86_64-freebsd" ,+X86_64_Linux = λ(_ : {}) → "x86_64-linux" , X86_64_Solaris = λ(_ : {}) →+"x86_64-solaris" } element ) ++ "," ++ result ) } status : < Empty : {} |+NonEmpty : Text > ) (< Empty : {} | NonEmpty : Text >.Empty {=}) ) : Text ) +++" " ++ x.key ++ " " ++ Integer/show (Natural/toInteger x.cores) ++ " " +++Integer/show (Natural/toInteger x.speedFactor) ++ " " ++ ( merge { Empty = λ(_ :+{}) → "", NonEmpty = λ(result : Text) → result } ( List/fold Text+x.supportedFeatures < Empty : {} | NonEmpty : Text > ( λ(element : Text) →+λ(status : < Empty : {} | NonEmpty : Text >) → merge { Empty = λ(_ : {}) → <+NonEmpty : Text | Empty : {} >.NonEmpty element , NonEmpty = λ(result : Text) →+< NonEmpty : Text | Empty : {} >.NonEmpty (element ++ "," ++ result) } status :+< Empty : {} | NonEmpty : Text > ) (< Empty : {} | NonEmpty : Text >.Empty {=})+) : Text ) ++ " " ++ ( merge { Empty = λ(_ : {}) → "", NonEmpty = λ(result :+Text) → result } ( List/fold Text x.mandatoryFeatures < Empty : {} | NonEmpty :+Text > ( λ(element : Text) → λ(status : < Empty : {} | NonEmpty : Text >) →+merge { Empty = λ(_ : {}) → < NonEmpty : Text | Empty : {} >.NonEmpty element ,+NonEmpty = λ(result : Text) → < NonEmpty : Text | Empty : {} >.NonEmpty+(element ++ "," ++ result) } status : < Empty : {} | NonEmpty : Text > ) (<+Empty : {} | NonEmpty : Text+>.Empty {=}) ) : Text ) ++ "\n" ++ y ) ""
+ benchmark/parser/examples/issue108.dhallb view

binary file changed (absent → 3818 bytes)

+ benchmark/parser/examples/kubernetes.dhallb view

file too large to diff

+ benchmark/parser/examples/normalize/ChurchEval.dhall view
@@ -0,0 +1,22 @@++let Nat = ∀(N : Type) → (N → N) → N → N+let n2  = λ(N : Type) → λ(s : N → N) → λ(z : N) → s (s z)+let n5  = λ(N : Type) → λ(s : N → N) → λ(z : N) → s (s (s (s (s z))))++let mul =+  λ(a : Nat) → λ(b : Nat) → λ(N : Type) → λ(s : N → N) → λ(z : N) → a N (b N s) z++let add =+  λ(a : Nat) → λ(b : Nat) → λ(N : Type) → λ(s : N → N) → λ(z : N) → a N s (b N s z)++let n10   = mul n2 n5+let n100  = mul n10 n10+let n1k   = mul n10 n100+let n10k  = mul n100 n100+let n100k = mul n10 n10k+let n1M   = mul n10k n100+let n5M   = mul n1M n5+let n10M  = mul n1M n10+let n20M  = mul n10M n2++in n1M Natural (λ (x:Natural) → x + 1) 0
+ benchmark/parser/examples/normalize/FunCompose.dhall view
@@ -0,0 +1,18 @@++let compose+    : ∀(a : Type) → ∀(b : Type) → ∀(c : Type) → (a → b) → (b → c) → a → c+    =   λ(A : Type)+      → λ(B : Type)+      → λ(C : Type)+      → λ(f : A → B)+      → λ(g : B → C)+      → λ(x : A)+      → g (f x)++let composeN : ∀ (a : Type) → Natural → (a → a) → a → a+    = λ (a : Type)+	→ λ (n : Natural)+	→ λ (f : a → a)+	→ Natural/fold n (a → a) (compose a a a f) (λ (x : a) → x)++in composeN Natural 100000 (λ (x : Natural) → x + 1) 0
+ benchmark/parser/examples/normalize/ListBench.dhall view
@@ -0,0 +1,75 @@++let iterate+    =   λ(n : Natural)+      → λ(a : Type)+      → λ(f : a → a)+      → λ(x : a)+      → List/build+        a+        (   λ(list : Type)+          → λ(cons : a → list → list)+          → List/fold+            { index : Natural, value : {} }+            ( List/indexed+              {}+              ( List/build+                {}+                (   λ(list : Type)+                  → λ(cons : {} → list → list)+                  → Natural/fold n list (cons {=})+                )+              )+            )+            list+            (   λ(y : { index : Natural, value : {} })+              → cons (Natural/fold y.index a f x)+            )+        )++let countTo =+  λ (x : Natural)+  → iterate x Natural (λ (x : Natural) → x + 1) 0++let sum =+  λ (xs : List Natural)+  → List/fold Natural xs Natural (λ (x : Natural) → λ (acc : Natural) → x + acc) 0+++let map+        : ∀(a : Type) → ∀(b : Type) → (a → b) → List a → List b+        =   λ(a : Type)+          → λ(b : Type)+          → λ(f : a → b)+          → λ(xs : List a)+          → List/build+            b+            (   λ(list : Type)+              → λ(cons : b → list → list)+              → List/fold a xs list (λ(x : a) → cons (f x))+            )++let any+        : ∀(a : Type) → (a → Bool) → List a → Bool+        =   λ(a : Type)+          → λ(f : a → Bool)+          → λ(xs : List a)+          → List/fold a xs Bool (λ(x : a) → λ(r : Bool) → f x || r) False++let filter+        : ∀(a : Type) → (a → Bool) → List a → List a+        =   λ(a : Type)+          → λ(f : a → Bool)+          → λ(xs : List a)+          → List/build+            a+            (   λ(list : Type)+              → λ(cons : a → list → list)+              → List/fold+                a+                xs+                list+                (λ(x : a) → λ(xs : list) → if f x then cons x xs else xs)+            )++in sum (filter Natural Natural/even+     (map Natural Natural (λ(x:Natural) → x + 10) (countTo 1000)))
+ benchmark/parser/examples/normalize/ListBenchAlt.dhall view
@@ -0,0 +1,45 @@++let iterate =+    λ(n : Natural)+  → λ(a : Type)+  → λ(f : a → a)+  → λ(x : a)+  → (Natural/fold n+      (a → List a → {fst:a, snd:List a})+	  (λ (hyp : a → List a → {fst:a, snd:List a}) →+	   λ (x : a) → λ (xs : List a)+	   → let tup = hyp x xs+	     in {fst = f (tup.fst), snd = tup.snd # [tup.fst]})+	  (λ (x : a) → λ (xs : List a) → {fst=x, snd=xs})+	  x ([] : List a)).snd++let countTo =+  λ (x : Natural)+  → iterate x Natural (λ (x : Natural) → x + 1) 0++let sum =+  λ (xs : List Natural)+  → List/fold Natural xs Natural (λ (x : Natural) → λ (acc : Natural) → x + acc) 0++let map+  =   λ(a : Type)+    → λ(b : Type)+    → λ(f : a → b)+    → λ(xs : List a)+	→ List/fold a xs (List b) (λ (x : a) → λ (xs : List b) → [f x] # xs) ([] : List b)++let any+  =   λ(a : Type)+        → λ(f : a → Bool)+        → λ(xs : List a)+        → List/fold a xs Bool (λ(x : a) → λ(r : Bool) → f x || r) False++let filter+  =   λ(a : Type)+    → λ(f : a → Bool)+    → λ(xs : List a)+	→ List/fold a xs (List a)+	    (λ (x : a) → λ (xs : List a) → if f x then [x] # xs else xs) ([] : List a)++in sum (filter Natural Natural/even+     (map Natural Natural (λ(x:Natural) → x + 10) (countTo 1000)))
dhall-lang/Prelude/Bool/and view
@@ -1,2 +1,3 @@-  ./and.dhall sha256:0b2114fa33cd76652e4360f012bc082718944fe4c5b28c975483178f8d9b0a6d+  missing+    sha256:0b2114fa33cd76652e4360f012bc082718944fe4c5b28c975483178f8d9b0a6d ? ./and.dhall
dhall-lang/Prelude/Bool/build view
@@ -1,2 +1,3 @@-  ./build.dhall sha256:add7cb9acacac705410088d876a7e4488e046a7aded304f06c51accffd7f1b7b+  missing+    sha256:add7cb9acacac705410088d876a7e4488e046a7aded304f06c51accffd7f1b7b ? ./build.dhall
+ dhall-lang/Prelude/Bool/equal.dhall view
@@ -0,0 +1,6 @@+--| Returns `True` if both arguments are equal and returns `False` otherwise+let equal+    : Bool -> Bool -> Bool+    = \(x : Bool) -> \(y : Bool) -> x == y++in  equal
dhall-lang/Prelude/Bool/even view
@@ -1,2 +1,3 @@-  ./even.dhall sha256:72a05ee550636a3acb768360fa51ba0db0326763e0cf1ceb737f0f3607fc0fe5+  missing+    sha256:72a05ee550636a3acb768360fa51ba0db0326763e0cf1ceb737f0f3607fc0fe5 ? ./even.dhall
dhall-lang/Prelude/Bool/fold view
@@ -1,2 +1,3 @@-  ./fold.dhall sha256:39f60baf3950268c2e849e91dc6279ee41cd6b81892d54020d4fcd2ce30a96ae+  missing+    sha256:39f60baf3950268c2e849e91dc6279ee41cd6b81892d54020d4fcd2ce30a96ae ? ./fold.dhall
dhall-lang/Prelude/Bool/not view
@@ -1,2 +1,3 @@-  ./not.dhall sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4+  missing+    sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4 ? ./not.dhall
dhall-lang/Prelude/Bool/odd view
@@ -1,2 +1,3 @@-  ./odd.dhall sha256:6360fca3a745de32bd186cc7b71487a6398cd47d5119064eae491872c41d1999+  missing+    sha256:6360fca3a745de32bd186cc7b71487a6398cd47d5119064eae491872c41d1999 ? ./odd.dhall
dhall-lang/Prelude/Bool/or view
@@ -1,2 +1,3 @@-  ./or.dhall sha256:5c50738e84e1c4fed8343ebd57608500e1b61ac1f502aa52d6d6edb5c20b99e4+  missing+    sha256:5c50738e84e1c4fed8343ebd57608500e1b61ac1f502aa52d6d6edb5c20b99e4 ? ./or.dhall
dhall-lang/Prelude/Bool/package.dhall view
@@ -1,25 +1,37 @@ { and =-      ./and.dhall sha256:0b2114fa33cd76652e4360f012bc082718944fe4c5b28c975483178f8d9b0a6d+      missing+        sha256:0b2114fa33cd76652e4360f012bc082718944fe4c5b28c975483178f8d9b0a6d     ? ./and.dhall , build =-      ./build.dhall sha256:add7cb9acacac705410088d876a7e4488e046a7aded304f06c51accffd7f1b7b+      missing+        sha256:add7cb9acacac705410088d876a7e4488e046a7aded304f06c51accffd7f1b7b     ? ./build.dhall+, equal =+      missing+        sha256:f0dc047ca14644c2a979bb126f2a3c6659ec770c66bd7beb70ae4a9d05815709+    ? ./equal.dhall , even =-      ./even.dhall sha256:72a05ee550636a3acb768360fa51ba0db0326763e0cf1ceb737f0f3607fc0fe5+      missing+        sha256:72a05ee550636a3acb768360fa51ba0db0326763e0cf1ceb737f0f3607fc0fe5     ? ./even.dhall , fold =-      ./fold.dhall sha256:39f60baf3950268c2e849e91dc6279ee41cd6b81892d54020d4fcd2ce30a96ae+      missing+        sha256:39f60baf3950268c2e849e91dc6279ee41cd6b81892d54020d4fcd2ce30a96ae     ? ./fold.dhall , not =-      ./not.dhall sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4+      missing+        sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4     ? ./not.dhall , odd =-      ./odd.dhall sha256:6360fca3a745de32bd186cc7b71487a6398cd47d5119064eae491872c41d1999+      missing+        sha256:6360fca3a745de32bd186cc7b71487a6398cd47d5119064eae491872c41d1999     ? ./odd.dhall , or =-      ./or.dhall sha256:5c50738e84e1c4fed8343ebd57608500e1b61ac1f502aa52d6d6edb5c20b99e4+      missing+        sha256:5c50738e84e1c4fed8343ebd57608500e1b61ac1f502aa52d6d6edb5c20b99e4     ? ./or.dhall , show =-      ./show.dhall sha256:f85f6d2d921c37a2122cb2e2f8a0170e305b699debd0e6df5ef3370d806b5f61+      missing+        sha256:f85f6d2d921c37a2122cb2e2f8a0170e305b699debd0e6df5ef3370d806b5f61     ? ./show.dhall }
dhall-lang/Prelude/Bool/show view
@@ -1,2 +1,3 @@-  ./show.dhall sha256:f85f6d2d921c37a2122cb2e2f8a0170e305b699debd0e6df5ef3370d806b5f61+  missing+    sha256:f85f6d2d921c37a2122cb2e2f8a0170e305b699debd0e6df5ef3370d806b5f61 ? ./show.dhall
+ dhall-lang/Prelude/Date/package.dhall view
@@ -0,0 +1,5 @@+{ show =+      missing+        sha256:8a0eb9732cbc3c8f161b7cb05b183493befacc4728d2d9b7ee1384f19106a5ff+    ? ./show.dhall+}
+ dhall-lang/Prelude/Date/show.dhall view
@@ -0,0 +1,15 @@+{-+Render a `Date` as `Text` using the same representation as Dhall source code+(i.e. `YYYY-MM-DD`)+-}+let show+    : Date → Text+    = Date/show++let example0 = assert : show 2000-09-02 ≡ "2000-09-02"++let example1 = assert : show 9999-12-31 ≡ "9999-12-31"++let example2 = assert : show 0000-01-01 ≡ "0000-01-01"++in  show
+ dhall-lang/Prelude/DirectoryTree/Access/Mask/Type.dhall view
@@ -0,0 +1,5 @@+{-|+A (total) set of access rights; See chmod(5) for an explanation of the flags.+For a partial set of of access rights see `Access`.+-}+{ execute : Bool, read : Bool, write : Bool }
+ dhall-lang/Prelude/DirectoryTree/Access/Mask/intersect.dhall view
@@ -0,0 +1,69 @@+{-|+@intersect a b@ intesects the flags of the two `Mask`s @a@ and @b@. This+resembles the bitwise "and", i.e. the value of a flag is 'True' if and only if+it is set to 'True' in both @a@ and @b@. As a consequence @intersect a rwx == a@+and @intersect a none == none@ for all @a@.+-}+let Mask =+        missing+          sha256:c0fa7626b69e117086439a7b4ee15d1a80e16e38fe2ccc13f55e6dd26030b4df+      ? ./Type.dhall++let intersect+    : Mask -> Mask -> Mask+    = \(m1 : Mask) ->+      \(m2 : Mask) ->+        { read = m1.read && m2.read+        , write = m1.write && m2.write+        , execute = m1.execute && m2.execute+        }++let example0 =+      let r =+              missing+                sha256:26d7fc8df6194a8051946eac88d0d7fecce690bff6819e69b3c74edf65ac027a+            ? ./r.dhall++      let w =+              missing+                sha256:9d10dfc672f61bbb2828c7be2121aae2502938c25adb47bb8cce3c40ba99821b+            ? ./w.dhall++      let x =+              missing+                sha256:a966fd88c05a5912a6daa8409e0c9e396f0a4810b51def1e1f62a95e18235f10+            ? ./x.dhall++      let rwx =+              missing+                sha256:cafda16b1ecc0d2f9a63f3aab229a02e18aebb054283c73e50517f1e3727cd27+            ? ./rwx.dhall++      let none =+              missing+                sha256:db6c3bb734bb3288441f2664379706052943eaba35c021326a600d41ca766925+            ? ./none.dhall++      in  assert : intersect r (intersect w (intersect x rwx)) === none++let example1 =+      \(a : Mask) ->+        let rwx =+                missing+                  sha256:cafda16b1ecc0d2f9a63f3aab229a02e18aebb054283c73e50517f1e3727cd27+              ? ./rwx.dhall++        in    assert+            :     intersect a rwx+              ===  { execute = a.execute, read = a.read, write = a.write }++let example2 =+      \(a : Mask) ->+        let none =+                missing+                  sha256:db6c3bb734bb3288441f2664379706052943eaba35c021326a600d41ca766925+              ? ./none.dhall++        in  assert : intersect a none === none++in  intersect
+ dhall-lang/Prelude/DirectoryTree/Access/Mask/invert.dhall view
@@ -0,0 +1,48 @@+{-|+Inverts the flags set in a `Mask`.+-}+let Mask =+        missing+          sha256:c0fa7626b69e117086439a7b4ee15d1a80e16e38fe2ccc13f55e6dd26030b4df+      ? ./Type.dhall++let Bool/not =+        missing+          sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4+      ? ../../../Bool/not.dhall++let invert+    : Mask -> Mask+    = \(m : Mask) ->+        { read = Bool/not m.read+        , write = Bool/not m.write+        , execute = Bool/not m.execute+        }++let example0 =+      let none =+              missing+                sha256:db6c3bb734bb3288441f2664379706052943eaba35c021326a600d41ca766925+            ? ./none.dhall++      let rwx =+              missing+                sha256:cafda16b1ecc0d2f9a63f3aab229a02e18aebb054283c73e50517f1e3727cd27+            ? ./rwx.dhall++      in  assert : invert rwx === none++let example1 =+      let none =+              missing+                sha256:db6c3bb734bb3288441f2664379706052943eaba35c021326a600d41ca766925+            ? ./none.dhall++      let rwx =+              missing+                sha256:cafda16b1ecc0d2f9a63f3aab229a02e18aebb054283c73e50517f1e3727cd27+            ? ./rwx.dhall++      in  assert : invert none === rwx++in  invert
+ dhall-lang/Prelude/DirectoryTree/Access/Mask/none.dhall view
@@ -0,0 +1,4 @@+  { read = False, write = False, execute = False }+:   missing+      sha256:c0fa7626b69e117086439a7b4ee15d1a80e16e38fe2ccc13f55e6dd26030b4df+  ? ./Type.dhall
+ dhall-lang/Prelude/DirectoryTree/Access/Mask/package.dhall view
@@ -0,0 +1,53 @@+{ Type =+      missing+        sha256:c0fa7626b69e117086439a7b4ee15d1a80e16e38fe2ccc13f55e6dd26030b4df+    ? ./Type.dhall+, intersect =+      missing+        sha256:7c7dab3e305f43cba556e0778b5a797cf8e9b1d1a6c6f6fe0ea311c329919663+    ? ./intersect.dhall+, invert =+      missing+        sha256:8807fb02f694fe2117f8a7f794e5afbb967ec36eac3405184bf9232c33cdd830+    ? ./invert.dhall+, none =+      missing+        sha256:db6c3bb734bb3288441f2664379706052943eaba35c021326a600d41ca766925+    ? ./none.dhall+, r =+      missing+        sha256:26d7fc8df6194a8051946eac88d0d7fecce690bff6819e69b3c74edf65ac027a+    ? ./r.dhall+, rw =+      missing+        sha256:c3cce19f462b841e64adafbdf2963699a0031f5fc08b041c8ad364483c544d8b+    ? ./rw.dhall+, rwx =+      missing+        sha256:cafda16b1ecc0d2f9a63f3aab229a02e18aebb054283c73e50517f1e3727cd27+    ? ./rwx.dhall+, rx =+      missing+        sha256:d9beaa853c0de6984c3e5b0e313b573942900f8024fd9aaad743d73df458dc5e+    ? ./rx.dhall+, toAccess =+      missing+        sha256:78fe016f0273b2551c8590da71bf204cc26d6879c6b84622d4d8ad5624328438+    ? ./toAccess.dhall+, toAccessWith =+      missing+        sha256:814ab74ad292c121620a1f468837d4a5473323423bf68c1bceca69e7b3c59077+    ? ./toAccessWith.dhall+, union =+      missing+        sha256:b40c4cbb266991e3f764af075e9db544b59c16b3d9aa680c0cf6cb7552da191f+    ? ./union.dhall+, w =+      missing+        sha256:9d10dfc672f61bbb2828c7be2121aae2502938c25adb47bb8cce3c40ba99821b+    ? ./w.dhall+, x =+      missing+        sha256:a966fd88c05a5912a6daa8409e0c9e396f0a4810b51def1e1f62a95e18235f10+    ? ./x.dhall+}
+ dhall-lang/Prelude/DirectoryTree/Access/Mask/r.dhall view
@@ -0,0 +1,4 @@+  { read = True, write = False, execute = False }+:   missing+      sha256:c0fa7626b69e117086439a7b4ee15d1a80e16e38fe2ccc13f55e6dd26030b4df+  ? ./Type.dhall
+ dhall-lang/Prelude/DirectoryTree/Access/Mask/rw.dhall view
@@ -0,0 +1,4 @@+  { read = True, write = True, execute = False }+:   missing+      sha256:c0fa7626b69e117086439a7b4ee15d1a80e16e38fe2ccc13f55e6dd26030b4df+  ? ./Type.dhall
+ dhall-lang/Prelude/DirectoryTree/Access/Mask/rwx.dhall view
@@ -0,0 +1,4 @@+  { read = True, write = True, execute = True }+:   missing+      sha256:c0fa7626b69e117086439a7b4ee15d1a80e16e38fe2ccc13f55e6dd26030b4df+  ? ./Type.dhall
+ dhall-lang/Prelude/DirectoryTree/Access/Mask/rx.dhall view
@@ -0,0 +1,4 @@+  { read = True, write = False, execute = True }+:   missing+      sha256:c0fa7626b69e117086439a7b4ee15d1a80e16e38fe2ccc13f55e6dd26030b4df+  ? ./Type.dhall
+ dhall-lang/Prelude/DirectoryTree/Access/Mask/toAccess.dhall view
@@ -0,0 +1,20 @@+{-|+Convert a `Mask` value to an `Access` value. For a partial conversion see+`toAccessWith`.+-}+let Access =+        missing+          sha256:50689ae80f8c8dcd6e7af33fbc20ea871afb92ec87104253cdbae01f838f6c38+      ? ../Type.dhall++let Mask =+        missing+          sha256:c0fa7626b69e117086439a7b4ee15d1a80e16e38fe2ccc13f55e6dd26030b4df+      ? ./Type.dhall++let toAccess+    : Mask -> Access+    = \(m : Mask) ->+        { execute = Some m.execute, read = Some m.read, write = Some m.write }++in  toAccess
+ dhall-lang/Prelude/DirectoryTree/Access/Mask/toAccessWith.dhall view
@@ -0,0 +1,42 @@+{-|+@toAccessWith x m@ converts some fields of a `Mask` @m@ to an `Access` setting:+If the respective field is set in the first `Mask` @x@, then the flag will be+set to the flags value given in @m@. Otherwise, the value set in @m@ is ignored+and the value of the flag in the result is `None`.++For a motivation of this function see the documenation on `toModeWith`.+-}+let Access =+        missing+          sha256:50689ae80f8c8dcd6e7af33fbc20ea871afb92ec87104253cdbae01f838f6c38+      ? ../Type.dhall++let Mask =+        missing+          sha256:c0fa7626b69e117086439a7b4ee15d1a80e16e38fe2ccc13f55e6dd26030b4df+      ? ./Type.dhall++let toAccessWith+    : Mask -> Mask -> Access+    = \(set : Mask) ->+      \(m : Mask) ->+        { execute = if set.execute then Some m.execute else None Bool+        , read = if set.read then Some m.read else None Bool+        , write = if set.write then Some m.write else None Bool+        }++let example0 =+      \(a : Mask) ->+        let Access/none =+                missing+                  sha256:955a2eed689139c811d4b9ef3dd8d0c484392b18c3bb8752c59fd69dbdaf4881+              ? ../none.dhall++        let none =+                missing+                  sha256:db6c3bb734bb3288441f2664379706052943eaba35c021326a600d41ca766925+              ? ./none.dhall++        in  assert : toAccessWith none a === Access/none++in  toAccessWith
+ dhall-lang/Prelude/DirectoryTree/Access/Mask/union.dhall view
@@ -0,0 +1,64 @@+{-|+@union a b@ combines the flags of the two `Mask`s @a@ and @b@. This resembles+the bitwise "or", i.e. the value of a flag is 'True' if it is set to 'True' in+either @a@ and @b@. As a consequence @union a rwx == rwx@ and+@union a none == a@ for all @a@.+-}+let Mask =+        missing+          sha256:c0fa7626b69e117086439a7b4ee15d1a80e16e38fe2ccc13f55e6dd26030b4df+      ? ./Type.dhall++let union+    : Mask -> Mask -> Mask+    = \(m1 : Mask) ->+      \(m2 : Mask) ->+        { read = m1.read || m2.read+        , write = m1.write || m2.write+        , execute = m1.execute || m2.execute+        }++let example0 =+      let r =+              missing+                sha256:26d7fc8df6194a8051946eac88d0d7fecce690bff6819e69b3c74edf65ac027a+            ? ./r.dhall++      let w =+              missing+                sha256:9d10dfc672f61bbb2828c7be2121aae2502938c25adb47bb8cce3c40ba99821b+            ? ./w.dhall++      let x =+              missing+                sha256:a966fd88c05a5912a6daa8409e0c9e396f0a4810b51def1e1f62a95e18235f10+            ? ./x.dhall++      let rwx =+              missing+                sha256:cafda16b1ecc0d2f9a63f3aab229a02e18aebb054283c73e50517f1e3727cd27+            ? ./rwx.dhall++      in  assert : union r (union w x) === rwx++let example1 =+      \(a : Mask) ->+        let rwx =+                missing+                  sha256:cafda16b1ecc0d2f9a63f3aab229a02e18aebb054283c73e50517f1e3727cd27+              ? ./rwx.dhall++        in  assert : union a rwx === rwx++let example1 =+      \(a : Mask) ->+        let none =+                missing+                  sha256:db6c3bb734bb3288441f2664379706052943eaba35c021326a600d41ca766925+              ? ./none.dhall++        in    assert+            :     union a none+              ===  { execute = a.execute, read = a.read, write = a.write }++in  union
+ dhall-lang/Prelude/DirectoryTree/Access/Mask/w.dhall view
@@ -0,0 +1,4 @@+  { read = False, write = True, execute = False }+:   missing+      sha256:c0fa7626b69e117086439a7b4ee15d1a80e16e38fe2ccc13f55e6dd26030b4df+  ? ./Type.dhall
+ dhall-lang/Prelude/DirectoryTree/Access/Mask/x.dhall view
@@ -0,0 +1,4 @@+  { read = False, write = False, execute = True }+:   missing+      sha256:c0fa7626b69e117086439a7b4ee15d1a80e16e38fe2ccc13f55e6dd26030b4df+  ? ./Type.dhall
+ dhall-lang/Prelude/DirectoryTree/Access/Type.dhall view
@@ -0,0 +1,5 @@+{-|+A (partial) set of access rights; See chmod(5) for an explanation of the flags.+For a total set of access rights see `Mask`.+-}+{ execute : Optional Bool, read : Optional Bool, write : Optional Bool }
+ dhall-lang/Prelude/DirectoryTree/Access/equal.dhall view
@@ -0,0 +1,29 @@+{-|+`equal` checks if two `Access` settings are equal.+-}+let Access =+        missing+          sha256:50689ae80f8c8dcd6e7af33fbc20ea871afb92ec87104253cdbae01f838f6c38+      ? ./Type.dhall++let Bool/equal =+        missing+          sha256:f0dc047ca14644c2a979bb126f2a3c6659ec770c66bd7beb70ae4a9d05815709+      ? ../../Bool/equal.dhall++let Optional/equal =+        missing+          sha256:5411888399fe9c6720f7f3b59caf5eff3e8e8c30402d09f34e46a4457649a35a+      ? ../../Optional/equal.dhall++let f+    : Optional Bool -> Optional Bool -> Bool+    = Optional/equal Bool Bool/equal++let equal+    : Access -> Access -> Bool+    = \(a1 : Access) ->+      \(a2 : Access) ->+        f a1.execute a2.execute && f a1.read a2.read && f a1.write a2.write++in  equal
+ dhall-lang/Prelude/DirectoryTree/Access/none.dhall view
@@ -0,0 +1,4 @@+  { read = None Bool, write = None Bool, execute = None Bool }+:   missing+      sha256:50689ae80f8c8dcd6e7af33fbc20ea871afb92ec87104253cdbae01f838f6c38+  ? ./Type.dhall
+ dhall-lang/Prelude/DirectoryTree/Access/package.dhall view
@@ -0,0 +1,17 @@+{ Mask =+      missing+        sha256:ed736de51ea15a2ef671eaa7219dfbf3138bb52acfd0ae17894acf2ec4b06369+    ? ./Mask/package.dhall+, Type =+      missing+        sha256:50689ae80f8c8dcd6e7af33fbc20ea871afb92ec87104253cdbae01f838f6c38+    ? ./Type.dhall+, equal =+      missing+        sha256:5fa90f55505780a7be942275d6bbb2b1f1fb7857364332ed732a0241c2165e53+    ? ./equal.dhall+, schema =+      missing+        sha256:7d33a584a42a5d92411d5ca623e27ccb397762905be86ecfd01b106719fae690+    ? ./schema.dhall+}
+ dhall-lang/Prelude/DirectoryTree/Access/schema.dhall view
@@ -0,0 +1,12 @@+{-|+A schema for blank access rights.+-}+{ Type =+      missing+        sha256:50689ae80f8c8dcd6e7af33fbc20ea871afb92ec87104253cdbae01f838f6c38+    ? ./Type.dhall+, default =+      missing+        sha256:955a2eed689139c811d4b9ef3dd8d0c484392b18c3bb8752c59fd69dbdaf4881+    ? ./none.dhall+}
+ dhall-lang/Prelude/DirectoryTree/Entry/BinaryFileEntry.dhall view
@@ -0,0 +1,6 @@+let Entry =+        missing+          sha256:75148ae19175750e38705e11cda8dcc775b2ac08f22518ff2ef3f33a6273ef15+      ? ./Type.dhall++in  Entry Bytes
+ dhall-lang/Prelude/DirectoryTree/Entry/DirectoryEntry.dhall view
@@ -0,0 +1,6 @@+let Entry =+        missing+          sha256:75148ae19175750e38705e11cda8dcc775b2ac08f22518ff2ef3f33a6273ef15+      ? ./Type.dhall++in  \(tree : Type) -> Entry (List tree)
+ dhall-lang/Prelude/DirectoryTree/Entry/Metadata.dhall view
@@ -0,0 +1,24 @@+{-|+An `Entry` without content. That in turn implies that the type of the entry+(i.e. whether it is a file or a directory) is not (yet) fixed as well.+-}+let User =+        missing+          sha256:8b25916612d2c9b17130d16b55c6bdb085dd118e692f72bf351a83b1d0ac8833+      ? ../User/Type.dhall++let Group =+        missing+          sha256:83e6e8846153d94abf6f879808c94f5cdba3f486cc9e392eb6124b1dc67368cf+      ? ../Group/Type.dhall++let Mode =+        missing+          sha256:f05819ec2145e7dabf4aa167338bee6d326aabd81355dcf0b078e358bd34ec60+      ? ../Mode/Type.dhall++in  { name : Text+    , user : Optional User+    , group : Optional Group+    , mode : Optional Mode+    }
+ dhall-lang/Prelude/DirectoryTree/Entry/TextFileEntry.dhall view
@@ -0,0 +1,6 @@+let Entry =+        missing+          sha256:75148ae19175750e38705e11cda8dcc775b2ac08f22518ff2ef3f33a6273ef15+      ? ./Type.dhall++in  Entry Text
+ dhall-lang/Prelude/DirectoryTree/Entry/Type.dhall view
@@ -0,0 +1,6 @@+let Metadata =+        missing+          sha256:8c240a00094238a73904af63ac0924b3e6aba1655312f20a2a27f88554e2febe+      ? ./Metadata.dhall++in  \(content : Type) -> Metadata //\\ { content : content }
+ dhall-lang/Prelude/DirectoryTree/Entry/binary-file.dhall view
@@ -0,0 +1,6 @@+let Entry =+        missing+          sha256:742610b2a13e55ae6e344b54aa8a7ee1bfec8e8b313a1132eae9286309b520e6+      ? ./entry.dhall++in  Entry Bytes
+ dhall-lang/Prelude/DirectoryTree/Entry/directory.dhall view
@@ -0,0 +1,6 @@+let Entry =+        missing+          sha256:742610b2a13e55ae6e344b54aa8a7ee1bfec8e8b313a1132eae9286309b520e6+      ? ./entry.dhall++in  \(tree : Type) -> Entry (List tree)
+ dhall-lang/Prelude/DirectoryTree/Entry/entry.dhall view
@@ -0,0 +1,24 @@+let Entry =+        missing+          sha256:75148ae19175750e38705e11cda8dcc775b2ac08f22518ff2ef3f33a6273ef15+      ? ./Type.dhall++let User =+        missing+          sha256:8b25916612d2c9b17130d16b55c6bdb085dd118e692f72bf351a83b1d0ac8833+      ? ../User/Type.dhall++let Group =+        missing+          sha256:83e6e8846153d94abf6f879808c94f5cdba3f486cc9e392eb6124b1dc67368cf+      ? ../Group/Type.dhall++let Mode =+        missing+          sha256:f05819ec2145e7dabf4aa167338bee6d326aabd81355dcf0b078e358bd34ec60+      ? ../Mode/Type.dhall++in  \(content : Type) ->+      { Type = Entry content+      , default = { user = None User, group = None Group, mode = None Mode }+      }
+ dhall-lang/Prelude/DirectoryTree/Entry/package.dhall view
@@ -0,0 +1,37 @@+{ BinaryFileEntry =+      missing+        sha256:f027db2893f6f38bbe6d868a91f22de530e85407237f00b147427c87d32bf55c+    ? ./BinaryFileEntry.dhall+, DirectoryEntry =+      missing+        sha256:163a4536fdd05ce122d793ceda01d03fcffb29463817ae8b7b5601bf4a06ce6e+    ? ./DirectoryEntry.dhall+, Metadata =+      missing+        sha256:8c240a00094238a73904af63ac0924b3e6aba1655312f20a2a27f88554e2febe+    ? ./Metadata.dhall+, TextFileEntry =+      missing+        sha256:23a8cb29d96aeb623501519d9a62c5c49659e8d1c30b4ae4f2399809e3fd3a01+    ? ./TextFileEntry.dhall+, Type =+      missing+        sha256:75148ae19175750e38705e11cda8dcc775b2ac08f22518ff2ef3f33a6273ef15+    ? ./Type.dhall+, binary-file =+      missing+        sha256:bd49df43268c259e3d0bef995917c3ab517ae7b98bf1faac8f4a7e8a602e3465+    ? ./binary-file.dhall+, directory =+      missing+        sha256:0bee17310a21efa5b06f139b6731fdcee4f9e0245ef711c2b0127b8938dfed2e+    ? ./directory.dhall+, entry =+      missing+        sha256:742610b2a13e55ae6e344b54aa8a7ee1bfec8e8b313a1132eae9286309b520e6+    ? ./entry.dhall+, text-file =+      missing+        sha256:c5d76fd43216668d03df9945183fe7b3c55486aedcc77324c3372bd63e283b78+    ? ./text-file.dhall+}
+ dhall-lang/Prelude/DirectoryTree/Entry/text-file.dhall view
@@ -0,0 +1,6 @@+let Entry =+        missing+          sha256:742610b2a13e55ae6e344b54aa8a7ee1bfec8e8b313a1132eae9286309b520e6+      ? ./entry.dhall++in  Entry Text
+ dhall-lang/Prelude/DirectoryTree/Group/Type.dhall view
@@ -0,0 +1,1 @@+< GroupId : Natural | GroupName : Text >
+ dhall-lang/Prelude/DirectoryTree/Group/id.dhall view
@@ -0,0 +1,6 @@+let Group =+        missing+          sha256:83e6e8846153d94abf6f879808c94f5cdba3f486cc9e392eb6124b1dc67368cf+      ? ./Type.dhall++in  Group.GroupId
+ dhall-lang/Prelude/DirectoryTree/Group/name.dhall view
@@ -0,0 +1,6 @@+let Group =+        missing+          sha256:83e6e8846153d94abf6f879808c94f5cdba3f486cc9e392eb6124b1dc67368cf+      ? ./Type.dhall++in  Group.GroupName
+ dhall-lang/Prelude/DirectoryTree/Group/package.dhall view
@@ -0,0 +1,13 @@+{ Type =+      missing+        sha256:83e6e8846153d94abf6f879808c94f5cdba3f486cc9e392eb6124b1dc67368cf+    ? ./Type.dhall+, id =+      missing+        sha256:2bf9e546f56a583243d419a652caba16ca4053df9ccb3c5b242506d86806944b+    ? ./id.dhall+, name =+      missing+        sha256:51ac5c407f2939ab0c80bf2896d292ee6049bd8ba10acda0af327a3777f2205d+    ? ./name.dhall+}
+ dhall-lang/Prelude/DirectoryTree/Mode/Mask/Type.dhall view
@@ -0,0 +1,10 @@+{-|+A complete mode with all access rights specified explicitely. For an incomplete+mode where some access rights might not be set see `Mode`.+-}+let Access/Mask =+        missing+          sha256:c0fa7626b69e117086439a7b4ee15d1a80e16e38fe2ccc13f55e6dd26030b4df+      ? ../../Access/Mask/Type.dhall++in  { user : Access/Mask, group : Access/Mask, other : Access/Mask }
+ dhall-lang/Prelude/DirectoryTree/Mode/Mask/all.dhall view
@@ -0,0 +1,9 @@+{-|+Permissions with all flags set: rwxrwxrwx+-}+let rwx =+        missing+          sha256:cafda16b1ecc0d2f9a63f3aab229a02e18aebb054283c73e50517f1e3727cd27+      ? ../../Access/Mask/rwx.dhall++in  { user = rwx, group = rwx, other = rwx }
+ dhall-lang/Prelude/DirectoryTree/Mode/Mask/directory.dhall view
@@ -0,0 +1,17 @@+{-|+Permissions commonly used for directories: rwxr-xr-x+-}+let rwx =+        missing+          sha256:cafda16b1ecc0d2f9a63f3aab229a02e18aebb054283c73e50517f1e3727cd27+      ? ../../Access/Mask/rwx.dhall++let rx =+        missing+          sha256:d9beaa853c0de6984c3e5b0e313b573942900f8024fd9aaad743d73df458dc5e+      ? ../../Access/Mask/rx.dhall++in    { user = rwx, group = rx, other = rx }+    :   missing+          sha256:4f97762058f24053e03997565a78800a5a2586159deaa265a4ee84a3d94ad471+      ? ./Type.dhall
+ dhall-lang/Prelude/DirectoryTree/Mode/Mask/executable.dhall view
@@ -0,0 +1,17 @@+{-|+Permissions commonly used for executable files: rwxr-xr-x+-}+let rwx =+        missing+          sha256:cafda16b1ecc0d2f9a63f3aab229a02e18aebb054283c73e50517f1e3727cd27+      ? ../../Access/Mask/rwx.dhall++let rx =+        missing+          sha256:d9beaa853c0de6984c3e5b0e313b573942900f8024fd9aaad743d73df458dc5e+      ? ../../Access/Mask/rx.dhall++in    { user = rwx, group = rx, other = rx }+    :   missing+          sha256:4f97762058f24053e03997565a78800a5a2586159deaa265a4ee84a3d94ad471+      ? ./Type.dhall
+ dhall-lang/Prelude/DirectoryTree/Mode/Mask/file.dhall view
@@ -0,0 +1,17 @@+{-|+Permissions commonly used for regular files: rw-r--r--+-}+let r =+        missing+          sha256:26d7fc8df6194a8051946eac88d0d7fecce690bff6819e69b3c74edf65ac027a+      ? ../../Access/Mask/r.dhall++let rw =+        missing+          sha256:c3cce19f462b841e64adafbdf2963699a0031f5fc08b041c8ad364483c544d8b+      ? ../../Access/Mask/rw.dhall++in    { user = rw, group = r, other = r }+    :   missing+          sha256:4f97762058f24053e03997565a78800a5a2586159deaa265a4ee84a3d94ad471+      ? ./Type.dhall
+ dhall-lang/Prelude/DirectoryTree/Mode/Mask/group.dhall view
@@ -0,0 +1,14 @@+{-|+Permissions with group flags set: ---rwx---+-}+let rwx =+        missing+          sha256:cafda16b1ecc0d2f9a63f3aab229a02e18aebb054283c73e50517f1e3727cd27+      ? ../../Access/Mask/rwx.dhall++let none =+        missing+          sha256:db6c3bb734bb3288441f2664379706052943eaba35c021326a600d41ca766925+      ? ../../Access/Mask/none.dhall++in  { user = none, group = rwx, other = none }
+ dhall-lang/Prelude/DirectoryTree/Mode/Mask/intersect.dhall view
@@ -0,0 +1,24 @@+{-|+Calculates the intersection of the access rights of two `Mask`s using+`Access/intersect`.+-}+let Mask =+        missing+          sha256:4f97762058f24053e03997565a78800a5a2586159deaa265a4ee84a3d94ad471+      ? ./Type.dhall++let Access/intersect =+        missing+          sha256:7c7dab3e305f43cba556e0778b5a797cf8e9b1d1a6c6f6fe0ea311c329919663+      ? ../../Access/Mask/intersect.dhall++let intersect+    : Mask -> Mask -> Mask+    = \(m1 : Mask) ->+      \(m2 : Mask) ->+        { user = Access/intersect m1.user m2.user+        , group = Access/intersect m1.group m2.group+        , other = Access/intersect m1.other m2.other+        }++in  intersect
+ dhall-lang/Prelude/DirectoryTree/Mode/Mask/invert.dhall view
@@ -0,0 +1,22 @@+{-|+Inverts each access right set in a `Mask` using `Access/invert`.+-}+let Mask =+        missing+          sha256:4f97762058f24053e03997565a78800a5a2586159deaa265a4ee84a3d94ad471+      ? ./Type.dhall++let Access/invert =+        missing+          sha256:8807fb02f694fe2117f8a7f794e5afbb967ec36eac3405184bf9232c33cdd830+      ? ../../Access/Mask/invert.dhall++let invert+    : Mask -> Mask+    = \(m : Mask) ->+        { user = Access/invert m.user+        , group = Access/invert m.group+        , other = Access/invert m.other+        }++in  invert
+ dhall-lang/Prelude/DirectoryTree/Mode/Mask/none.dhall view
@@ -0,0 +1,12 @@+{-|+Permissions with no flags set: ---------+-}+let none =+        missing+          sha256:db6c3bb734bb3288441f2664379706052943eaba35c021326a600d41ca766925+      ? ../../Access/Mask/none.dhall++in    { user = none, group = none, other = none }+    :   missing+          sha256:4f97762058f24053e03997565a78800a5a2586159deaa265a4ee84a3d94ad471+      ? ./Type.dhall
+ dhall-lang/Prelude/DirectoryTree/Mode/Mask/other.dhall view
@@ -0,0 +1,14 @@+{-|+Permissions with other flags set: ------rwx+-}+let rwx =+        missing+          sha256:cafda16b1ecc0d2f9a63f3aab229a02e18aebb054283c73e50517f1e3727cd27+      ? ../../Access/Mask/rwx.dhall++let none =+        missing+          sha256:db6c3bb734bb3288441f2664379706052943eaba35c021326a600d41ca766925+      ? ../../Access/Mask/none.dhall++in  { user = none, group = none, other = rwx }
+ dhall-lang/Prelude/DirectoryTree/Mode/Mask/package.dhall view
@@ -0,0 +1,41 @@+{ Type =+      missing+        sha256:4f97762058f24053e03997565a78800a5a2586159deaa265a4ee84a3d94ad471+    ? ./Type.dhall+, directory =+      missing+        sha256:a43f235f0caa25c7cabd89ac5d77e466e0c0ebf3339046993c18e481930243fd+    ? ./directory.dhall+, executable =+      missing+        sha256:a43f235f0caa25c7cabd89ac5d77e466e0c0ebf3339046993c18e481930243fd+    ? ./executable.dhall+, file =+      missing+        sha256:32d34228d48a707996272d1c9681171ddcd6651f72eeb3de9727d1c26ba99df3+    ? ./file.dhall+, intersect =+      missing+        sha256:146be962523ef619d3a250699f977b69c3e5f6c24b975453f351c0e807266fc8+    ? ./intersect.dhall+, invert =+      missing+        sha256:07a13d8c233d0a9fd6b3a11475987c10619072fec882c96bc5499bfb3c01e9b2+    ? ./invert.dhall+, none =+      missing+        sha256:7cac21e2b72cadf3ee0bf10680df4902ca73b6ee070219df5eac1a24cd66ccdf+    ? ./none.dhall+, toMode =+      missing+        sha256:af2b0dab799374afa0a2f28551446760ff29f4697c200da0a8b0a8def7feee2a+    ? ./toMode.dhall+, toModeWith =+      missing+        sha256:b92327bec9141cc1a55bc3f11ae2584af0883b94fe2513376fc40f1da5ade9b2+    ? ./toModeWith.dhall+, union =+      missing+        sha256:3bb32fc6ea21f661571e46d90e450e0340b2f2b65482ba7bd1a30514e1b39fc2+    ? ./union.dhall+}
+ dhall-lang/Prelude/DirectoryTree/Mode/Mask/toMode.dhall view
@@ -0,0 +1,28 @@+{-|+Convert a `Mask` value to a `Mode` value. For a partial conversion see+`toModeWith`.+-}+let Mode =+        missing+          sha256:f05819ec2145e7dabf4aa167338bee6d326aabd81355dcf0b078e358bd34ec60+      ? ../Type.dhall++let Mask =+        missing+          sha256:4f97762058f24053e03997565a78800a5a2586159deaa265a4ee84a3d94ad471+      ? ./Type.dhall++let Access/toAccess =+        missing+          sha256:78fe016f0273b2551c8590da71bf204cc26d6879c6b84622d4d8ad5624328438+      ? ../../Access/Mask/toAccess.dhall++let toMode+    : Mask -> Mode+    = \(m : Mask) ->+        { user = Some (Access/toAccess m.user)+        , group = Some (Access/toAccess m.group)+        , other = Some (Access/toAccess m.other)+        }++in  toMode
+ dhall-lang/Prelude/DirectoryTree/Mode/Mask/toModeWith.dhall view
@@ -0,0 +1,149 @@+{-|+@toModeWith x m@ converts some fields of a `Mask` @m@ to a `Mode`: If the+respective field is set in the first `Mask` @x@, then the flag will be set to+the flags value given in @m@. Otherwise, the value set in @m@ is ignored and the+value of the flag in the result is `None`.++The function is motivated by the following use case:+Alice has her umask set to 022 and new files will have permissions set to+rw-r--r--. Bob has the umask set to 077, hence newly created files will have+rw------- permissions. Now Eve distributes Dhall code writing a file with the+following mode to the filesystem:+```dhall+let mask = ./other.dhall++let permissions = ./all.dhall++in+toModeWith mask permissions+```+The written file will have rw-r--rwx permissions for Alice and rw----rwx+permissions for Bob as the `toModeWith mask` produces a `Mode` that will only+apply the permissions for the 'other' part.+-}+let Access =+        missing+          sha256:50689ae80f8c8dcd6e7af33fbc20ea871afb92ec87104253cdbae01f838f6c38+      ? ../../Access/Type.dhall++let Access/Mask =+        missing+          sha256:c0fa7626b69e117086439a7b4ee15d1a80e16e38fe2ccc13f55e6dd26030b4df+      ? ../../Access/Mask/Type.dhall++let Mode =+        missing+          sha256:f05819ec2145e7dabf4aa167338bee6d326aabd81355dcf0b078e358bd34ec60+      ? ../Type.dhall++let Mask =+        missing+          sha256:4f97762058f24053e03997565a78800a5a2586159deaa265a4ee84a3d94ad471+      ? ./Type.dhall++let Access/equal =+        missing+          sha256:5fa90f55505780a7be942275d6bbb2b1f1fb7857364332ed732a0241c2165e53+      ? ../../Access/equal.dhall++let Access/toAccessWith =+        missing+          sha256:814ab74ad292c121620a1f468837d4a5473323423bf68c1bceca69e7b3c59077+      ? ../../Access/Mask/toAccessWith.dhall++let f+    : Access/Mask -> Access/Mask -> Optional Access+    = \(set : Access/Mask) ->+      \(m : Access/Mask) ->+        let x = Access/toAccessWith set m++        in  if    Access/equal+                    { execute = None Bool, read = None Bool, write = None Bool }+                    x+            then  None Access+            else  Some x++let toModeWith+    : Mask -> Mask -> Mode+    = \(set : Mask) ->+      \(m : Mask) ->+        { user = f set.user m.user+        , group = f set.group m.group+        , other = f set.other m.other+        }++let example0 =+      \(a : Mask) ->+        let none =+                missing+                  sha256:7cac21e2b72cadf3ee0bf10680df4902ca73b6ee070219df5eac1a24cd66ccdf+              ? ./none.dhall++        let Mode/none =+                missing+                  sha256:0ed46da7e6acbdff9e4c9e27a9f2770075a7cd6cb6bb565765c62093df1b5563+              ? ../none.dhall++        in  assert : toModeWith none a === Mode/none++let example1 =+      \(a : Mask) ->+        let toMode =+                missing+                  sha256:af2b0dab799374afa0a2f28551446760ff29f4697c200da0a8b0a8def7feee2a+              ? ./toMode.dhall++        let all =+                missing+                  sha256:758415eca8dfee675dfef93ace9af82abb36bb3319b8e6295537ed18f9b5d3dd+              ? ./all.dhall++        in  assert : toModeWith all a === toMode a++let example2 =+      let mask =+              missing+                sha256:94bf82678d8d1c4f370a96f3831d3ad4464fbee508ffb37e93a479a1d9ee25cf+            ? ./other.dhall++      let permissions =+              missing+                sha256:758415eca8dfee675dfef93ace9af82abb36bb3319b8e6295537ed18f9b5d3dd+            ? ./all.dhall++      let rwx = { read = Some True, write = Some True, execute = Some True }++      in    assert+          :     toModeWith mask permissions+            ===  { user = None Access, group = None Access, other = Some rwx }++let example3 =+      let union =+              missing+                sha256:3bb32fc6ea21f661571e46d90e450e0340b2f2b65482ba7bd1a30514e1b39fc2+            ? ./union.dhall++      let group =+              missing+                sha256:faa567630372f77bb5cd2fa4fe7cb4760d2f9f79e35df80917e6e0064decf7cf+            ? ./group.dhall++      let other =+              missing+                sha256:94bf82678d8d1c4f370a96f3831d3ad4464fbee508ffb37e93a479a1d9ee25cf+            ? ./other.dhall++      let permissions =+              missing+                sha256:758415eca8dfee675dfef93ace9af82abb36bb3319b8e6295537ed18f9b5d3dd+            ? ./all.dhall++      let mask = union group other++      let rwx = { read = Some True, write = Some True, execute = Some True }++      in    assert+          :     toModeWith mask permissions+            ===  { user = None Access, group = Some rwx, other = Some rwx }++in  toModeWith
+ dhall-lang/Prelude/DirectoryTree/Mode/Mask/union.dhall view
@@ -0,0 +1,24 @@+{-|+Calculates the union of the access rights set by both `Mask`s using+`Access/union`.+-}+let Mask =+        missing+          sha256:4f97762058f24053e03997565a78800a5a2586159deaa265a4ee84a3d94ad471+      ? ./Type.dhall++let Access/union =+        missing+          sha256:b40c4cbb266991e3f764af075e9db544b59c16b3d9aa680c0cf6cb7552da191f+      ? ../../Access/Mask/union.dhall++let union+    : Mask -> Mask -> Mask+    = \(m1 : Mask) ->+      \(m2 : Mask) ->+        { user = Access/union m1.user m2.user+        , group = Access/union m1.group m2.group+        , other = Access/union m1.other m2.other+        }++in  union
+ dhall-lang/Prelude/DirectoryTree/Mode/Mask/user.dhall view
@@ -0,0 +1,14 @@+{-|+Permissions with all user flags set: rwx------+-}+let rwx =+        missing+          sha256:cafda16b1ecc0d2f9a63f3aab229a02e18aebb054283c73e50517f1e3727cd27+      ? ../../Access/Mask/rwx.dhall++let none =+        missing+          sha256:db6c3bb734bb3288441f2664379706052943eaba35c021326a600d41ca766925+      ? ../../Access/Mask/none.dhall++in  { user = rwx, group = none, other = none }
+ dhall-lang/Prelude/DirectoryTree/Mode/Type.dhall view
@@ -0,0 +1,10 @@+{-|+An incomplete mode where some access rights might not be set explicitely. For a+complete mode with all access rights specified explicitely see `Mask`.+-}+let Access =+        missing+          sha256:50689ae80f8c8dcd6e7af33fbc20ea871afb92ec87104253cdbae01f838f6c38+      ? ../Access/Type.dhall++in  { user : Optional Access, group : Optional Access, other : Optional Access }
+ dhall-lang/Prelude/DirectoryTree/Mode/equal.dhall view
@@ -0,0 +1,34 @@+{-|+`equal` checks if two `Mode`s are equal.+-}+let Access =+        missing+          sha256:50689ae80f8c8dcd6e7af33fbc20ea871afb92ec87104253cdbae01f838f6c38+      ? ../Access/Type.dhall++let Mode =+        missing+          sha256:f05819ec2145e7dabf4aa167338bee6d326aabd81355dcf0b078e358bd34ec60+      ? ./Type.dhall++let Access/equal =+        missing+          sha256:5fa90f55505780a7be942275d6bbb2b1f1fb7857364332ed732a0241c2165e53+      ? ../Access/equal.dhall++let Optional/equal =+        missing+          sha256:5411888399fe9c6720f7f3b59caf5eff3e8e8c30402d09f34e46a4457649a35a+      ? ../../Optional/equal.dhall++let f+    : Optional Access -> Optional Access -> Bool+    = Optional/equal Access Access/equal++let equal+    : Mode -> Mode -> Bool+    = \(m1 : Mode) ->+      \(m2 : Mode) ->+        f m1.user m2.user && f m1.group m2.group && f m1.other m2.other++in  equal
+ dhall-lang/Prelude/DirectoryTree/Mode/none.dhall view
@@ -0,0 +1,9 @@+let Access =+        missing+          sha256:50689ae80f8c8dcd6e7af33fbc20ea871afb92ec87104253cdbae01f838f6c38+      ? ../Access/Type.dhall++in    { user = None Access, group = None Access, other = None Access }+    :   missing+          sha256:f05819ec2145e7dabf4aa167338bee6d326aabd81355dcf0b078e358bd34ec60+      ? ./Type.dhall
+ dhall-lang/Prelude/DirectoryTree/Mode/package.dhall view
@@ -0,0 +1,17 @@+{ Mask =+      missing+        sha256:ce2c7ac1b81c2184b906cdd07c79936ba0eaf0445f1e383f53fd18d688ee7044+    ? ./Mask/package.dhall+, Type =+      missing+        sha256:f05819ec2145e7dabf4aa167338bee6d326aabd81355dcf0b078e358bd34ec60+    ? ./Type.dhall+, equal =+      missing+        sha256:32fee2d3a56a2162d6c98fb63d47d31f98b352f22cc60c8b506011c9b5230e56+    ? ./equal.dhall+, schema =+      missing+        sha256:49f8eff9612d761c1bd424299b68317ad0f3ba325e4d22ec8acb550c2f1c0a40+    ? ./schema.dhall+}
+ dhall-lang/Prelude/DirectoryTree/Mode/schema.dhall view
@@ -0,0 +1,12 @@+{-|+A schema for a blank file mode.+-}+{ Type =+      missing+        sha256:f05819ec2145e7dabf4aa167338bee6d326aabd81355dcf0b078e358bd34ec60+    ? ./Type.dhall+, default =+      missing+        sha256:0ed46da7e6acbdff9e4c9e27a9f2770075a7cd6cb6bb565765c62093df1b5563+    ? ./none.dhall+}
+ dhall-lang/Prelude/DirectoryTree/Tree/Make.dhall view
@@ -0,0 +1,20 @@+let Directory =+        missing+          sha256:163a4536fdd05ce122d793ceda01d03fcffb29463817ae8b7b5601bf4a06ce6e+      ? ../Entry/DirectoryEntry.dhall++let BinaryFile =+        missing+          sha256:f027db2893f6f38bbe6d868a91f22de530e85407237f00b147427c87d32bf55c+      ? ../Entry/BinaryFileEntry.dhall++let TextFile =+        missing+          sha256:23a8cb29d96aeb623501519d9a62c5c49659e8d1c30b4ae4f2399809e3fd3a01+      ? ../Entry/TextFileEntry.dhall++in  \(tree : Type) ->+      { directory : Directory tree -> tree+      , binary-file : BinaryFile -> tree+      , file : TextFile -> tree+      }
+ dhall-lang/Prelude/DirectoryTree/Tree/Type.dhall view
@@ -0,0 +1,6 @@+let Make =+        missing+          sha256:33c52c16f76b41c3635b57a38ce0286f1ad8b3163a3f07a3b41b808ac5bfeb5b+      ? ./Make.dhall++in  forall (tree : Type) -> forall (make : Make tree) -> List tree
+ dhall-lang/Prelude/DirectoryTree/Tree/makeTree.dhall view
@@ -0,0 +1,32 @@+{-|+@makeTree tree make parents x@ places the tree @x@ below the directory @parent@.+@parent@ is given as a list of 'Metadata' values where each of those will be+used to create the respective level of the directory tree.+-}+let Make =+        missing+          sha256:33c52c16f76b41c3635b57a38ce0286f1ad8b3163a3f07a3b41b808ac5bfeb5b+      ? ./Make.dhall++let Metadata =+        missing+          sha256:8c240a00094238a73904af63ac0924b3e6aba1655312f20a2a27f88554e2febe+      ? ../Entry/Metadata.dhall++let makeTree+    : forall (tree : Type) -> Make tree -> List Metadata -> tree -> tree+    = \(tree : Type) ->+      \(make : Make tree) ->+      \(parents : List Metadata) ->+      \(leaf : tree) ->+        List/fold+          Metadata+          parents+          tree+          ( \(directory : Metadata) ->+            \(result : tree) ->+              make.directory (directory /\ { content = [ result ] })+          )+          leaf++in  makeTree
+ dhall-lang/Prelude/DirectoryTree/Tree/makeTreeFromList.dhall view
@@ -0,0 +1,42 @@+{-|+@makeTreeFromList tree make parents xs@ places the trees @xs@ below the+directory @parent@. @parent@ is given as a non-empty list of 'Metadata' values+where each of those will be used to create the respective level of the directory+tree.+-}+let Make =+        missing+          sha256:33c52c16f76b41c3635b57a38ce0286f1ad8b3163a3f07a3b41b808ac5bfeb5b+      ? ./Make.dhall++let Metadata =+        missing+          sha256:8c240a00094238a73904af63ac0924b3e6aba1655312f20a2a27f88554e2febe+      ? ../Entry/Metadata.dhall++let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ../../NonEmpty/Type.dhall++let makeTreesFromList =+        missing+          sha256:02fce5b194da66c2f98bd05af0a3bfdccf0b57d7971f17bcafee436652d9a88e+      ? ./makeTreesFromList.dhall++let makeTreeFromList+    : forall (tree : Type) ->+      Make tree ->+      NonEmpty Metadata ->+      List tree ->+        tree+    = \(tree : Type) ->+      \(make : Make tree) ->+      \(parents : NonEmpty Metadata) ->+      \(leaves : List tree) ->+        make.directory+          (     parents.head+            /\  { content = makeTreesFromList tree make parents.tail leaves }+          )++in  makeTreeFromList
+ dhall-lang/Prelude/DirectoryTree/Tree/makeTreesFromList.dhall view
@@ -0,0 +1,36 @@+{-|+@makeTreesFromList tree make parents xs@ places the trees @xs@ below the+directory @parent@. @parent@ is given as a list of 'Metadata' values where each+of those will be used to create the respective level of the directory tree.+-}+let Make =+        missing+          sha256:33c52c16f76b41c3635b57a38ce0286f1ad8b3163a3f07a3b41b808ac5bfeb5b+      ? ./Make.dhall++let Metadata =+        missing+          sha256:8c240a00094238a73904af63ac0924b3e6aba1655312f20a2a27f88554e2febe+      ? ../Entry/Metadata.dhall++let makeTreesFromList+    : forall (tree : Type) ->+      Make tree ->+      List Metadata ->+      List tree ->+        List tree+    = \(tree : Type) ->+      \(make : Make tree) ->+      \(parents : List Metadata) ->+      \(leaves : List tree) ->+        List/fold+          Metadata+          parents+          (List tree)+          ( \(directory : Metadata) ->+            \(content : List tree) ->+              [ make.directory (directory /\ { content }) ]+          )+          leaves++in  makeTreesFromList
+ dhall-lang/Prelude/DirectoryTree/Tree/package.dhall view
@@ -0,0 +1,21 @@+{ Make =+      missing+        sha256:33c52c16f76b41c3635b57a38ce0286f1ad8b3163a3f07a3b41b808ac5bfeb5b+    ? ./Make.dhall+, Type =+      missing+        sha256:60b4d351213c6d851d7b2163ada40290b3c492a27326a2066fdec1a3915fb33b+    ? ./Type.dhall+, makeTree =+      missing+        sha256:2c1339fa63b4947864e1a6eede3c296288b53cf91a09d0d6881ae56790342e44+    ? ./makeTree.dhall+, makeTreeFromList =+      missing+        sha256:b894c9398e123d7262320684ac6301c2efe44d9d4f5a303b99d14e9be6b3150f+    ? ./makeTreeFromList.dhall+, makeTreesFromList =+      missing+        sha256:02fce5b194da66c2f98bd05af0a3bfdccf0b57d7971f17bcafee436652d9a88e+    ? ./makeTreesFromList.dhall+}
+ dhall-lang/Prelude/DirectoryTree/User/Type.dhall view
@@ -0,0 +1,1 @@+< UserId : Natural | UserName : Text >
+ dhall-lang/Prelude/DirectoryTree/User/id.dhall view
@@ -0,0 +1,6 @@+let User =+        missing+          sha256:8b25916612d2c9b17130d16b55c6bdb085dd118e692f72bf351a83b1d0ac8833+      ? ./Type.dhall++in  User.UserId
+ dhall-lang/Prelude/DirectoryTree/User/name.dhall view
@@ -0,0 +1,6 @@+let User =+        missing+          sha256:8b25916612d2c9b17130d16b55c6bdb085dd118e692f72bf351a83b1d0ac8833+      ? ./Type.dhall++in  User.UserName
+ dhall-lang/Prelude/DirectoryTree/User/package.dhall view
@@ -0,0 +1,13 @@+{ Type =+      missing+        sha256:8b25916612d2c9b17130d16b55c6bdb085dd118e692f72bf351a83b1d0ac8833+    ? ./Type.dhall+, id =+      missing+        sha256:b572ca9f08a04e8e472f1b6141fd71ff27cc7f22d1e72be50eba5f54798b5a6d+    ? ./id.dhall+, name =+      missing+        sha256:9cfd68599bbd626d3f32c9caa3f09b358ecc08659ef2540b24a4b17b49027015+    ? ./name.dhall+}
+ dhall-lang/Prelude/DirectoryTree/package.dhall view
@@ -0,0 +1,25 @@+{ Access =+      missing+        sha256:12f2ac90297a81c6e5a548bbf568fc7c93c906a6528432aa74faab6ec859de30+    ? ./Access/package.dhall+, Entry =+      missing+        sha256:795db8b6c2bc28fdff6fbcc832c5b4cb6931c1f62ffa84674280c24d4f2eacd8+    ? ./Entry/package.dhall+, Group =+      missing+        sha256:76a0d7e4606bdb91ab001b245cbd411939333b3fc3934ecbb5d41982d1ea001f+    ? ./Group/package.dhall+, Mode =+      missing+        sha256:6687ff7703fe9abdc4af9b3404af3d1c7d21a523d10a0c0b57d102a0bd87843f+    ? ./Mode/package.dhall+, Tree =+      missing+        sha256:6a64c27fa8a0c95830a4cc836651257235da0d985b7f93d11813cdb7a72e646b+    ? ./Tree/package.dhall+, User =+      missing+        sha256:eee7762ea4769371278907a4e33b3808d88430dda32dfc0536dc9bb2bb49d46a+    ? ./User/package.dhall+}
dhall-lang/Prelude/Double/package.dhall view
@@ -1,4 +1,5 @@ { show =-      ./show.dhall sha256:ae645813cc4d8505a265df4d7564c95482f62bb3e07fc81681959599b6cee04f+      missing+        sha256:ae645813cc4d8505a265df4d7564c95482f62bb3e07fc81681959599b6cee04f     ? ./show.dhall }
dhall-lang/Prelude/Double/show view
@@ -1,2 +1,3 @@-  ./show.dhall sha256:ae645813cc4d8505a265df4d7564c95482f62bb3e07fc81681959599b6cee04f+  missing+    sha256:ae645813cc4d8505a265df4d7564c95482f62bb3e07fc81681959599b6cee04f ? ./show.dhall
dhall-lang/Prelude/Function/compose view
@@ -1,2 +1,3 @@-  ./compose.dhall sha256:65ad8bbea530b3d8968785a7cf4a9a7976b67059aa15e3b61fcba600a40ae013+  missing+    sha256:65ad8bbea530b3d8968785a7cf4a9a7976b67059aa15e3b61fcba600a40ae013 ? ./compose.dhall
dhall-lang/Prelude/Function/compose.dhall view
@@ -1,12 +1,12 @@ --| Compose two functions into one. let compose     : ∀(a : Type) → ∀(b : Type) → ∀(c : Type) → (a → b) → (b → c) → a → c-    = λ(A : Type) →-      λ(B : Type) →-      λ(C : Type) →-      λ(f : A → B) →-      λ(g : B → C) →-      λ(x : A) →+    = λ(a : Type) →+      λ(b : Type) →+      λ(c : Type) →+      λ(f : a → b) →+      λ(g : b → c) →+      λ(x : a) →         g (f x)  let example0 =
+ dhall-lang/Prelude/Function/composeList.dhall view
@@ -0,0 +1,35 @@+{-|+Composes a list of functions starting from the left.+-}+let compose =+        missing+          sha256:65ad8bbea530b3d8968785a7cf4a9a7976b67059aa15e3b61fcba600a40ae013+      ? ./compose.dhall++let identity =+        missing+          sha256:f78b96792b459cb664f41c6119bd8897dd04353a3343521d436cd82ad71cb4d4+      ? ./identity.dhall++let composeList+    : ∀(a : Type) → List (a → a) → a → a+    = λ(a : Type) →+      λ(functions : List (a → a)) →+        List/fold (a → a) functions (a → a) (compose a a a) (identity a)++let example0 =+        assert+      :   composeList+            Natural+            [ λ(x : Natural) → x * 2, λ(x : Natural) → x + 1 ]+            1+        ≡ 3++let property0 =+      λ(a : Type) →+      λ(f : a → a) →+      λ(g : a → a) →+      λ(h : a → a) →+        assert : composeList a [ f, g, h ] ≡ (λ(x : a) → h (g (f x)))++in  composeList
dhall-lang/Prelude/Function/identity view
@@ -1,2 +1,3 @@-  ./identity.dhall sha256:f78b96792b459cb664f41c6119bd8897dd04353a3343521d436cd82ad71cb4d4+  missing+    sha256:f78b96792b459cb664f41c6119bd8897dd04353a3343521d436cd82ad71cb4d4 ? ./identity.dhall
dhall-lang/Prelude/Function/package.dhall view
@@ -1,7 +1,13 @@ { compose =-      ./compose.dhall sha256:65ad8bbea530b3d8968785a7cf4a9a7976b67059aa15e3b61fcba600a40ae013+      missing+        sha256:65ad8bbea530b3d8968785a7cf4a9a7976b67059aa15e3b61fcba600a40ae013     ? ./compose.dhall+, composeList =+      missing+        sha256:2c6931544d8b5a5b14514098c07bd1813f67b16834588d056df3c0bc2e489937+    ? ./composeList.dhall , identity =-      ./identity.dhall sha256:f78b96792b459cb664f41c6119bd8897dd04353a3343521d436cd82ad71cb4d4+      missing+        sha256:f78b96792b459cb664f41c6119bd8897dd04353a3343521d436cd82ad71cb4d4     ? ./identity.dhall }
dhall-lang/Prelude/Integer/abs view
@@ -1,2 +1,3 @@-  ./abs.dhall sha256:35212fcbe1e60cb95b033a4a9c6e45befca4a298aa9919915999d09e69ddced1+  missing+    sha256:35212fcbe1e60cb95b033a4a9c6e45befca4a298aa9919915999d09e69ddced1 ? ./abs.dhall
dhall-lang/Prelude/Integer/add view
@@ -1,2 +1,3 @@-  ./add.dhall sha256:7da1306a0bf87c5668beead2a1db1b18861e53d7ce1f38057b2964b649f59c3b+  missing+    sha256:7da1306a0bf87c5668beead2a1db1b18861e53d7ce1f38057b2964b649f59c3b ? ./add.dhall
dhall-lang/Prelude/Integer/add.dhall view
@@ -1,6 +1,7 @@ --| `add m n` computes `m + n`. let Integer/subtract =-        ./subtract.dhall sha256:a34d36272fa8ae4f1ec8b56222fe8dc8a2ec55ec6538b840de0cbe207b006fda+        missing+          sha256:a34d36272fa8ae4f1ec8b56222fe8dc8a2ec55ec6538b840de0cbe207b006fda       ? ./subtract.dhall  let add
dhall-lang/Prelude/Integer/clamp view
@@ -1,2 +1,3 @@-  ./clamp.dhall sha256:ea42096cf3e024fadfaf910e0b839005b0ea7514fff11e5a3950a77694d9c5d2+  missing+    sha256:ea42096cf3e024fadfaf910e0b839005b0ea7514fff11e5a3950a77694d9c5d2 ? ./clamp.dhall
dhall-lang/Prelude/Integer/equal view
@@ -1,2 +1,3 @@-  ./equal.dhall sha256:2d99a205086aa77eea17ae1dab22c275f3eb007bccdc8d9895b93497ebfc39f8+  missing+    sha256:2d99a205086aa77eea17ae1dab22c275f3eb007bccdc8d9895b93497ebfc39f8 ? ./equal.dhall
dhall-lang/Prelude/Integer/equal.dhall view
@@ -1,6 +1,7 @@ --| `equal` checks if two Integers are equal. let Natural/equal =-        ../Natural/equal.dhall sha256:7f108edfa35ddc7cebafb24dc073478e93a802e13b5bc3fd22f4768c9b066e60+        missing+          sha256:7f108edfa35ddc7cebafb24dc073478e93a802e13b5bc3fd22f4768c9b066e60       ? ../Natural/equal.dhall  let equal
dhall-lang/Prelude/Integer/greaterThan view
@@ -1,2 +1,3 @@-  ./greaterThan.dhall sha256:d23affd73029fc9aaf867c2c7b86510ca2802d3f0d1f3e1d1a93ffd87b7cb64b+  missing+    sha256:d23affd73029fc9aaf867c2c7b86510ca2802d3f0d1f3e1d1a93ffd87b7cb64b ? ./greaterThan.dhall
dhall-lang/Prelude/Integer/greaterThan.dhall view
@@ -1,10 +1,12 @@ --| `greaterThan` checks if one Integer is greater than another. let Bool/not =-        ../Bool/not.dhall sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4+        missing+          sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4       ? ../Bool/not.dhall  let lessThanEqual =-        ./lessThanEqual.dhall sha256:e3cca9f3942f81fa78a2bea23c0c24519c67cfe438116c38e797e12dcd26f6bc+        missing+          sha256:e3cca9f3942f81fa78a2bea23c0c24519c67cfe438116c38e797e12dcd26f6bc       ? ./lessThanEqual.dhall  let greaterThan
dhall-lang/Prelude/Integer/greaterThanEqual view
@@ -1,2 +1,3 @@-  ./greaterThanEqual.dhall sha256:a9fa2dc5cd6067a23b39d7fe8d14a63109583b320429fb0e446658a5aae0a958+  missing+    sha256:a9fa2dc5cd6067a23b39d7fe8d14a63109583b320429fb0e446658a5aae0a958 ? ./greaterThanEqual.dhall
dhall-lang/Prelude/Integer/greaterThanEqual.dhall view
@@ -2,7 +2,8 @@ `greaterThanEqual` checks if one Integer is greater than or equal to another. -} let lessThanEqual =-        ./lessThanEqual.dhall sha256:e3cca9f3942f81fa78a2bea23c0c24519c67cfe438116c38e797e12dcd26f6bc+        missing+          sha256:e3cca9f3942f81fa78a2bea23c0c24519c67cfe438116c38e797e12dcd26f6bc       ? ./lessThanEqual.dhall  let greaterThanEqual
dhall-lang/Prelude/Integer/lessThan view
@@ -1,2 +1,3 @@-  ./lessThan.dhall sha256:eeaa0081d10c6c97464ef193c40f1aa5cbb12f0202972ab42f3d310c2fd6a3f0+  missing+    sha256:eeaa0081d10c6c97464ef193c40f1aa5cbb12f0202972ab42f3d310c2fd6a3f0 ? ./lessThan.dhall
dhall-lang/Prelude/Integer/lessThan.dhall view
@@ -1,6 +1,7 @@ --| `lessThan` checks if one Integer is less than another. let greaterThan =-        ./greaterThan.dhall sha256:d23affd73029fc9aaf867c2c7b86510ca2802d3f0d1f3e1d1a93ffd87b7cb64b+        missing+          sha256:d23affd73029fc9aaf867c2c7b86510ca2802d3f0d1f3e1d1a93ffd87b7cb64b       ? ./greaterThan.dhall  let lessThan
dhall-lang/Prelude/Integer/lessThanEqual view
@@ -1,2 +1,3 @@-  ./lessThanEqual.dhall sha256:e3cca9f3942f81fa78a2bea23c0c24519c67cfe438116c38e797e12dcd26f6bc+  missing+    sha256:e3cca9f3942f81fa78a2bea23c0c24519c67cfe438116c38e797e12dcd26f6bc ? ./lessThanEqual.dhall
dhall-lang/Prelude/Integer/lessThanEqual.dhall view
@@ -1,18 +1,22 @@ --| `lessThanEqual` checks if one Integer is less than or equal to another. let Natural/greaterThanEqual =-        ../Natural/greaterThanEqual.dhall sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4+        missing+          sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4       ? ../Natural/greaterThanEqual.dhall  let Natural/lessThanEqual =-        ../Natural/lessThanEqual.dhall sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99+        missing+          sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99       ? ../Natural/lessThanEqual.dhall  let nonPositive =-        ./nonPositive.dhall sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b+        missing+          sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b       ? ./nonPositive.dhall  let nonNegative =-        ./nonNegative.dhall sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663+        missing+          sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663       ? ./nonNegative.dhall  let lessThanEqual
dhall-lang/Prelude/Integer/multiply view
@@ -1,2 +1,3 @@-  ./multiply.dhall sha256:dcb1ed7c8475ece8d67db92cd249fc728541778ff82509e28c3760e341880e4d+  missing+    sha256:dcb1ed7c8475ece8d67db92cd249fc728541778ff82509e28c3760e341880e4d ? ./multiply.dhall
dhall-lang/Prelude/Integer/multiply.dhall view
@@ -1,7 +1,7 @@ --| `multiply m n` computes `m * n`.- let nonPositive =-        ./nonPositive.dhall sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b+        missing+          sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b       ? ./nonPositive.dhall  let multiplyNonNegative =
dhall-lang/Prelude/Integer/negate view
@@ -1,2 +1,3 @@-  ./negate.dhall sha256:2373c992e1de93634bc6a8781eb073b2a92a70170133e49762a785f3a136df5d+  missing+    sha256:2373c992e1de93634bc6a8781eb073b2a92a70170133e49762a785f3a136df5d ? ./negate.dhall
dhall-lang/Prelude/Integer/negative view
@@ -1,2 +1,3 @@-  ./negative.dhall sha256:23e4b3c61eea9e878a7f83bf25fd0ea2c6a6d60174890d65be885828b690a570+  missing+    sha256:23e4b3c61eea9e878a7f83bf25fd0ea2c6a6d60174890d65be885828b690a570 ? ./negative.dhall
dhall-lang/Prelude/Integer/negative.dhall view
@@ -4,7 +4,8 @@ `negative` is more efficient than `./lessThan +0` or `./lessThanEqual -1`. -} let positive =-        ./positive.dhall sha256:7bdbf50fcdb83d01f74c7e2a92bf5c9104eff5d8c5b4587e9337f0caefcfdbe3+        missing+          sha256:7bdbf50fcdb83d01f74c7e2a92bf5c9104eff5d8c5b4587e9337f0caefcfdbe3       ? ./positive.dhall  let negative
dhall-lang/Prelude/Integer/nonNegative view
@@ -1,2 +1,3 @@-  ./nonNegative.dhall sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663+  missing+    sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663 ? ./nonNegative.dhall
dhall-lang/Prelude/Integer/nonNegative.dhall view
@@ -4,7 +4,8 @@ `nonNegative` is more efficient than `./greaterThanEqual +0` or `./greaterThan -1`. -} let nonPositive =-        ./nonPositive.dhall sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b+        missing+          sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b       ? ./nonPositive.dhall  let nonNegative
dhall-lang/Prelude/Integer/nonPositive view
@@ -1,2 +1,3 @@-  ./nonPositive.dhall sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b+  missing+    sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b ? ./nonPositive.dhall
dhall-lang/Prelude/Integer/package.dhall view
@@ -1,55 +1,73 @@ { abs =-      ./abs.dhall sha256:35212fcbe1e60cb95b033a4a9c6e45befca4a298aa9919915999d09e69ddced1+      missing+        sha256:35212fcbe1e60cb95b033a4a9c6e45befca4a298aa9919915999d09e69ddced1     ? ./abs.dhall , add =-      ./add.dhall sha256:7da1306a0bf87c5668beead2a1db1b18861e53d7ce1f38057b2964b649f59c3b+      missing+        sha256:7da1306a0bf87c5668beead2a1db1b18861e53d7ce1f38057b2964b649f59c3b     ? ./add.dhall , clamp =-      ./clamp.dhall sha256:ea42096cf3e024fadfaf910e0b839005b0ea7514fff11e5a3950a77694d9c5d2+      missing+        sha256:ea42096cf3e024fadfaf910e0b839005b0ea7514fff11e5a3950a77694d9c5d2     ? ./clamp.dhall , equal =-      ./equal.dhall sha256:2d99a205086aa77eea17ae1dab22c275f3eb007bccdc8d9895b93497ebfc39f8+      missing+        sha256:2d99a205086aa77eea17ae1dab22c275f3eb007bccdc8d9895b93497ebfc39f8     ? ./equal.dhall , greaterThan =-      ./greaterThan.dhall sha256:d23affd73029fc9aaf867c2c7b86510ca2802d3f0d1f3e1d1a93ffd87b7cb64b+      missing+        sha256:d23affd73029fc9aaf867c2c7b86510ca2802d3f0d1f3e1d1a93ffd87b7cb64b     ? ./greaterThan.dhall , greaterThanEqual =-      ./greaterThanEqual.dhall sha256:a9fa2dc5cd6067a23b39d7fe8d14a63109583b320429fb0e446658a5aae0a958+      missing+        sha256:a9fa2dc5cd6067a23b39d7fe8d14a63109583b320429fb0e446658a5aae0a958     ? ./greaterThanEqual.dhall , lessThan =-      ./lessThan.dhall sha256:eeaa0081d10c6c97464ef193c40f1aa5cbb12f0202972ab42f3d310c2fd6a3f0+      missing+        sha256:eeaa0081d10c6c97464ef193c40f1aa5cbb12f0202972ab42f3d310c2fd6a3f0     ? ./lessThan.dhall , lessThanEqual =-      ./lessThanEqual.dhall sha256:e3cca9f3942f81fa78a2bea23c0c24519c67cfe438116c38e797e12dcd26f6bc+      missing+        sha256:e3cca9f3942f81fa78a2bea23c0c24519c67cfe438116c38e797e12dcd26f6bc     ? ./lessThanEqual.dhall , multiply =-      ./multiply.dhall sha256:dcb1ed7c8475ece8d67db92cd249fc728541778ff82509e28c3760e341880e4d+      missing+        sha256:dcb1ed7c8475ece8d67db92cd249fc728541778ff82509e28c3760e341880e4d     ? ./multiply.dhall , negate =-      ./negate.dhall sha256:2373c992e1de93634bc6a8781eb073b2a92a70170133e49762a785f3a136df5d+      missing+        sha256:2373c992e1de93634bc6a8781eb073b2a92a70170133e49762a785f3a136df5d     ? ./negate.dhall , negative =-      ./negative.dhall sha256:23e4b3c61eea9e878a7f83bf25fd0ea2c6a6d60174890d65be885828b690a570+      missing+        sha256:23e4b3c61eea9e878a7f83bf25fd0ea2c6a6d60174890d65be885828b690a570     ? ./negative.dhall , nonNegative =-      ./nonNegative.dhall sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663+      missing+        sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663     ? ./nonNegative.dhall , nonPositive =-      ./nonPositive.dhall sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b+      missing+        sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b     ? ./nonPositive.dhall , positive =-      ./positive.dhall sha256:7bdbf50fcdb83d01f74c7e2a92bf5c9104eff5d8c5b4587e9337f0caefcfdbe3+      missing+        sha256:7bdbf50fcdb83d01f74c7e2a92bf5c9104eff5d8c5b4587e9337f0caefcfdbe3     ? ./positive.dhall , show =-      ./show.dhall sha256:ecf8b0594cd5181bc45d3b7ea0d44d3ba9ad5dac6ec17bb8968beb65f4b1baa9+      missing+        sha256:ecf8b0594cd5181bc45d3b7ea0d44d3ba9ad5dac6ec17bb8968beb65f4b1baa9     ? ./show.dhall , subtract =-      ./subtract.dhall sha256:a34d36272fa8ae4f1ec8b56222fe8dc8a2ec55ec6538b840de0cbe207b006fda+      missing+        sha256:a34d36272fa8ae4f1ec8b56222fe8dc8a2ec55ec6538b840de0cbe207b006fda     ? ./subtract.dhall , toDouble =-      ./toDouble.dhall sha256:77bc5d635dc4d952f37cc96f2a681d5ac503b4e8b21fc00055b1946adb5beda7+      missing+        sha256:77bc5d635dc4d952f37cc96f2a681d5ac503b4e8b21fc00055b1946adb5beda7     ? ./toDouble.dhall , toNatural =-      ./toNatural.dhall sha256:4d128730d74e7f832e53873cb5204aa91b79758be5ce4e1aa991fe1951304a0e+      missing+        sha256:4d128730d74e7f832e53873cb5204aa91b79758be5ce4e1aa991fe1951304a0e     ? ./toNatural.dhall }
dhall-lang/Prelude/Integer/positive view
@@ -1,2 +1,3 @@-  ./positive.dhall sha256:7bdbf50fcdb83d01f74c7e2a92bf5c9104eff5d8c5b4587e9337f0caefcfdbe3+  missing+    sha256:7bdbf50fcdb83d01f74c7e2a92bf5c9104eff5d8c5b4587e9337f0caefcfdbe3 ? ./positive.dhall
dhall-lang/Prelude/Integer/positive.dhall view
@@ -4,11 +4,13 @@ `positive` is more efficient than `./greaterThan +0` or `./greaterThanEqual +1`. -} let not =-        ../Bool/not.dhall sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4+        missing+          sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4       ? ../Bool/not.dhall  let nonPositive =-        ./nonPositive.dhall sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b+        missing+          sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b       ? ./nonPositive.dhall  let positive
dhall-lang/Prelude/Integer/show view
@@ -1,2 +1,3 @@-  ./show.dhall sha256:ecf8b0594cd5181bc45d3b7ea0d44d3ba9ad5dac6ec17bb8968beb65f4b1baa9+  missing+    sha256:ecf8b0594cd5181bc45d3b7ea0d44d3ba9ad5dac6ec17bb8968beb65f4b1baa9 ? ./show.dhall
dhall-lang/Prelude/Integer/subtract view
@@ -1,2 +1,3 @@-  ./subtract.dhall sha256:a34d36272fa8ae4f1ec8b56222fe8dc8a2ec55ec6538b840de0cbe207b006fda+  missing+    sha256:a34d36272fa8ae4f1ec8b56222fe8dc8a2ec55ec6538b840de0cbe207b006fda ? ./subtract.dhall
dhall-lang/Prelude/Integer/subtract.dhall view
@@ -1,6 +1,7 @@ --| `subtract m n` computes `n - m`. let nonPositive =-        ./nonPositive.dhall sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b+        missing+          sha256:e00a852eed5b84ff60487097d8aadce53c9e5301f53ff4954044bd68949fac3b       ? ./nonPositive.dhall  let subtractNonNegative =
dhall-lang/Prelude/Integer/toDouble view
@@ -1,2 +1,3 @@-  ./toDouble.dhall sha256:77bc5d635dc4d952f37cc96f2a681d5ac503b4e8b21fc00055b1946adb5beda7+  missing+    sha256:77bc5d635dc4d952f37cc96f2a681d5ac503b4e8b21fc00055b1946adb5beda7 ? ./toDouble.dhall
dhall-lang/Prelude/Integer/toNatural view
@@ -1,2 +1,3 @@-  ./toNatural.dhall sha256:4d128730d74e7f832e53873cb5204aa91b79758be5ce4e1aa991fe1951304a0e+  missing+    sha256:4d128730d74e7f832e53873cb5204aa91b79758be5ce4e1aa991fe1951304a0e ? ./toNatural.dhall
dhall-lang/Prelude/Integer/toNatural.dhall view
@@ -2,7 +2,8 @@ Convert an `Integer` to an `Optional Natural`, with negative numbers becoming `None Natural`. -} let nonNegative =-        ./nonNegative.dhall sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663+        missing+          sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663       ? ./nonNegative.dhall  let toNatural
dhall-lang/Prelude/JSON/Format view
@@ -1,2 +1,3 @@-  ./Format.dhall sha256:d7936b510cfc091faa994652af0eb5feb889cd44bc989edbe4f1eb8c5623caac+  missing+    sha256:d7936b510cfc091faa994652af0eb5feb889cd44bc989edbe4f1eb8c5623caac ? ./Format.dhall
dhall-lang/Prelude/JSON/Format.dhall view
@@ -4,5 +4,4 @@ You should not need to use this type directly, simply use `./render` or `./renderYAML` as appropriate. -}- < YAML | JSON >
dhall-lang/Prelude/JSON/Nesting view
@@ -1,2 +1,3 @@-  ./Nesting.dhall sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335+  missing+    sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335 ? ./Nesting.dhall
dhall-lang/Prelude/JSON/Tagged view
@@ -1,2 +1,3 @@-  ./Tagged.dhall sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194+  missing+    sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194 ? ./Tagged.dhall
dhall-lang/Prelude/JSON/Tagged.dhall view
@@ -65,7 +65,8 @@     = λ(a : Type) →         { field : Text         , nesting :-              ./Nesting.dhall sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335+              missing+                sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335             ? ./Nesting.dhall         , contents : a         }
dhall-lang/Prelude/JSON/Type view
@@ -1,2 +1,3 @@-  ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759+  missing+    sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759 ? ./Type.dhall
dhall-lang/Prelude/JSON/array view
@@ -1,2 +1,3 @@-  ./array.dhall sha256:fb6346a9c63638fe3c59f8108e19eebdbddc51389ec5570bab4c25f890ccccc8+  missing+    sha256:fb6346a9c63638fe3c59f8108e19eebdbddc51389ec5570bab4c25f890ccccc8 ? ./array.dhall
dhall-lang/Prelude/JSON/array.dhall view
@@ -13,11 +13,13 @@ ``` -} let JSON =-        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759+        missing+          sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759       ? ./Type.dhall  let List/map =-        ../List/map.dhall sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680+        missing+          sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680       ? ../List/map.dhall  let array
dhall-lang/Prelude/JSON/bool view
@@ -1,2 +1,3 @@-  ./bool.dhall sha256:e043d9ed01e5b45899059e128243f3dae7ce65f293f0015ce816fc36d30f7f39+  missing+    sha256:e043d9ed01e5b45899059e128243f3dae7ce65f293f0015ce816fc36d30f7f39 ? ./bool.dhall
dhall-lang/Prelude/JSON/bool.dhall view
@@ -12,7 +12,8 @@ ``` -} let JSON =-        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759+        missing+          sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759       ? ./Type.dhall  let bool
dhall-lang/Prelude/JSON/core.dhall view
@@ -8,48 +8,63 @@ `package.dhall` to avoid import cycles. -} { Type =-      ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759+      missing+        sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759     ? ./Type.dhall , Tagged =-      ./Tagged.dhall sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194+      missing+        sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194     ? ./Tagged.dhall , Nesting =-      ./Nesting.dhall sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335+      missing+        sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335     ? ./Nesting.dhall , keyText =-      ./keyText.dhall sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc+      missing+        sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc     ? ./keyText.dhall , keyValue =-      ./keyValue.dhall sha256:a0a97199d280c4cce72ffcbbf93b7ceda0a569cf4d173ac98e0aaaa78034b98c+      missing+        sha256:a0a97199d280c4cce72ffcbbf93b7ceda0a569cf4d173ac98e0aaaa78034b98c     ? ./keyValue.dhall , string =-      ./string.dhall sha256:7ddb3a3b9f3ed09ed011d621a10ad9825185cd03503be98a81d42f6afb77940e+      missing+        sha256:7ddb3a3b9f3ed09ed011d621a10ad9825185cd03503be98a81d42f6afb77940e     ? ./string.dhall , number =-      ./number.dhall sha256:e70162c73c4978ad0d0d99505f61c7d990f3abadfcc08b34388b29c0934a7a32+      missing+        sha256:e70162c73c4978ad0d0d99505f61c7d990f3abadfcc08b34388b29c0934a7a32     ? ./number.dhall , double =-      ./double.dhall sha256:e70162c73c4978ad0d0d99505f61c7d990f3abadfcc08b34388b29c0934a7a32+      missing+        sha256:e70162c73c4978ad0d0d99505f61c7d990f3abadfcc08b34388b29c0934a7a32     ? ./double.dhall , integer =-      ./integer.dhall sha256:c81a417397fc6f62155ec71fdd8d2047f981f0881295b307de3dd88747bf7e40+      missing+        sha256:c81a417397fc6f62155ec71fdd8d2047f981f0881295b307de3dd88747bf7e40     ? ./integer.dhall , natural =-      ./natural.dhall sha256:a839dc6789f19f820e9cbf70c60f41f3b057c59ece1d226d04db5aca447eb0e5+      missing+        sha256:a839dc6789f19f820e9cbf70c60f41f3b057c59ece1d226d04db5aca447eb0e5     ? ./natural.dhall , object =-      ./object.dhall sha256:869aede785c34798be9f9fd457ece73e7f683f352ae4555f791516a365faf4ac+      missing+        sha256:869aede785c34798be9f9fd457ece73e7f683f352ae4555f791516a365faf4ac     ? ./object.dhall , array =-      ./array.dhall sha256:fb6346a9c63638fe3c59f8108e19eebdbddc51389ec5570bab4c25f890ccccc8+      missing+        sha256:fb6346a9c63638fe3c59f8108e19eebdbddc51389ec5570bab4c25f890ccccc8     ? ./array.dhall , bool =-      ./bool.dhall sha256:e043d9ed01e5b45899059e128243f3dae7ce65f293f0015ce816fc36d30f7f39+      missing+        sha256:e043d9ed01e5b45899059e128243f3dae7ce65f293f0015ce816fc36d30f7f39     ? ./bool.dhall , null =-      ./null.dhall sha256:1eeb9aee38eb8dde0e64efbaf60f24612c8194cc00b510bfb627c2ee2e1877b8+      missing+        sha256:1eeb9aee38eb8dde0e64efbaf60f24612c8194cc00b510bfb627c2ee2e1877b8     ? ./null.dhall , renderInteger =-      ./renderInteger.dhall sha256:15b8d2ae46d5002832741927af787761df49798c911e2bf85db7a7b9cb5c078c+      missing+        sha256:15b8d2ae46d5002832741927af787761df49798c911e2bf85db7a7b9cb5c078c     ? ./renderInteger.dhall }
dhall-lang/Prelude/JSON/double view
@@ -1,2 +1,3 @@-  ./double.dhall sha256:e70162c73c4978ad0d0d99505f61c7d990f3abadfcc08b34388b29c0934a7a32+  missing+    sha256:e70162c73c4978ad0d0d99505f61c7d990f3abadfcc08b34388b29c0934a7a32 ? ./double.dhall
dhall-lang/Prelude/JSON/double.dhall view
@@ -12,7 +12,8 @@ ``` -} let JSON =-        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759+        missing+          sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759       ? ./Type.dhall  let double
dhall-lang/Prelude/JSON/integer view
@@ -1,2 +1,3 @@-  ./integer.dhall sha256:c81a417397fc6f62155ec71fdd8d2047f981f0881295b307de3dd88747bf7e40+  missing+    sha256:c81a417397fc6f62155ec71fdd8d2047f981f0881295b307de3dd88747bf7e40 ? ./integer.dhall
dhall-lang/Prelude/JSON/integer.dhall view
@@ -12,7 +12,8 @@ ``` -} let JSON =-        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759+        missing+          sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759       ? ./Type.dhall  let integer
dhall-lang/Prelude/JSON/keyText view
@@ -1,2 +1,3 @@-  ./keyText.dhall sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc+  missing+    sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc ? ./keyText.dhall
dhall-lang/Prelude/JSON/keyText.dhall view
@@ -1,2 +1,3 @@-  ../Map/keyText.dhall sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc+  missing+    sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc ? ../Map/keyText.dhall
dhall-lang/Prelude/JSON/keyValue view
@@ -1,2 +1,3 @@-  ./keyValue.dhall sha256:a0a97199d280c4cce72ffcbbf93b7ceda0a569cf4d173ac98e0aaaa78034b98c+  missing+    sha256:a0a97199d280c4cce72ffcbbf93b7ceda0a569cf4d173ac98e0aaaa78034b98c ? ./keyValue.dhall
dhall-lang/Prelude/JSON/keyValue.dhall view
@@ -1,2 +1,3 @@-  ../Map/keyValue.dhall sha256:a0a97199d280c4cce72ffcbbf93b7ceda0a569cf4d173ac98e0aaaa78034b98c+  missing+    sha256:a0a97199d280c4cce72ffcbbf93b7ceda0a569cf4d173ac98e0aaaa78034b98c ? ../Map/keyValue.dhall
dhall-lang/Prelude/JSON/natural view
@@ -1,2 +1,3 @@-  ./natural.dhall sha256:a839dc6789f19f820e9cbf70c60f41f3b057c59ece1d226d04db5aca447eb0e5+  missing+    sha256:a839dc6789f19f820e9cbf70c60f41f3b057c59ece1d226d04db5aca447eb0e5 ? ./natural.dhall
dhall-lang/Prelude/JSON/natural.dhall view
@@ -8,7 +8,8 @@ ``` -} let JSON =-        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759+        missing+          sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759       ? ./Type.dhall  let natural
dhall-lang/Prelude/JSON/null view
@@ -1,2 +1,3 @@-  ./null.dhall sha256:1eeb9aee38eb8dde0e64efbaf60f24612c8194cc00b510bfb627c2ee2e1877b8+  missing+    sha256:1eeb9aee38eb8dde0e64efbaf60f24612c8194cc00b510bfb627c2ee2e1877b8 ? ./null.dhall
dhall-lang/Prelude/JSON/null.dhall view
@@ -8,7 +8,8 @@ ``` -} let JSON =-        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759+        missing+          sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759       ? ./Type.dhall  let null
dhall-lang/Prelude/JSON/number view
@@ -1,2 +1,3 @@-  ./number.dhall sha256:e70162c73c4978ad0d0d99505f61c7d990f3abadfcc08b34388b29c0934a7a32+  missing+    sha256:e70162c73c4978ad0d0d99505f61c7d990f3abadfcc08b34388b29c0934a7a32 ? ./number.dhall
dhall-lang/Prelude/JSON/number.dhall view
@@ -12,11 +12,13 @@ ``` -} let JSON =-        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759+        missing+          sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759       ? ./Type.dhall  let double =-        ./double.dhall sha256:e70162c73c4978ad0d0d99505f61c7d990f3abadfcc08b34388b29c0934a7a32+        missing+          sha256:e70162c73c4978ad0d0d99505f61c7d990f3abadfcc08b34388b29c0934a7a32       ? ./double.dhall  let number
dhall-lang/Prelude/JSON/object view
@@ -1,2 +1,3 @@-  ./object.dhall sha256:869aede785c34798be9f9fd457ece73e7f683f352ae4555f791516a365faf4ac+  missing+    sha256:869aede785c34798be9f9fd457ece73e7f683f352ae4555f791516a365faf4ac ? ./object.dhall
dhall-lang/Prelude/JSON/object.dhall view
@@ -19,11 +19,13 @@ ``` -} let JSON =-        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759+        missing+          sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759       ? ./Type.dhall  let List/map =-        ../List/map.dhall sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680+        missing+          sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680       ? ../List/map.dhall  let object
dhall-lang/Prelude/JSON/omitNullFields view
@@ -1,2 +1,3 @@-  ./omitNullFields.dhall sha256:e6850e70094540b75edeb46f4d6038324a62def8d63544a1e9541f79739db6f0+  missing+    sha256:e6850e70094540b75edeb46f4d6038324a62def8d63544a1e9541f79739db6f0 ? ./omitNullFields.dhall
dhall-lang/Prelude/JSON/omitNullFields.dhall view
@@ -3,15 +3,18 @@ for a configuration to encode absent fields -} let JSON =-        ./core.dhall sha256:5dc1135d5481cfd6fde625aaed9fcbdb7aa7c14f2e76726aa5fdef028a5c10f5+        missing+          sha256:5dc1135d5481cfd6fde625aaed9fcbdb7aa7c14f2e76726aa5fdef028a5c10f5       ? ./core.dhall  let List/concatMap =-        ../List/concatMap.dhall sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64+        missing+          sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64       ? ../List/concatMap.dhall  let List/map =-        ../List/map.dhall sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680+        missing+          sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680       ? ../List/map.dhall  let omitNullFields
dhall-lang/Prelude/JSON/package.dhall view
@@ -1,19 +1,29 @@   { render =-        ./render.dhall sha256:b5e5aee66b8fc018b50e1019a76340deafe5f8176854ea3611476d79990785da+        missing+          sha256:36befdd8bb5a1c2b372709da245a8d074533b86429e137b894c08ad16fa34836       ? ./render.dhall+  , renderCompact =+        missing+          sha256:e6c8809fbe193fddd430f94350d69cefd45e7aaf8bd379e51b750fde75008562+      ? ./renderCompact.dhall   , renderYAML =-        ./renderYAML.dhall sha256:dad92a120956ae852be7496d1e1955bbf3f60834ab2ad32641269098f2846477+        missing+          sha256:bc71449397bbf48103c3ebbdd570cd27313115e94b2b1b96761d257d5c02d478       ? ./renderYAML.dhall   , omitNullFields =-        ./omitNullFields.dhall sha256:e6850e70094540b75edeb46f4d6038324a62def8d63544a1e9541f79739db6f0+        missing+          sha256:e6850e70094540b75edeb46f4d6038324a62def8d63544a1e9541f79739db6f0       ? ./omitNullFields.dhall   , tagInline =-        ./tagInline.dhall sha256:49559ac11906ba6cc9eac25753e31e7addb13bc760df108024174c55523984c4+        missing+          sha256:49559ac11906ba6cc9eac25753e31e7addb13bc760df108024174c55523984c4       ? ./tagInline.dhall   , tagNested =-        ./tagNested.dhall sha256:93a7415853b7677c832246efadc8e880c1b641a23589286a836a384ca311d26f+        missing+          sha256:93a7415853b7677c832246efadc8e880c1b641a23589286a836a384ca311d26f       ? ./tagNested.dhall   }-∧ (   ./core.dhall sha256:5dc1135d5481cfd6fde625aaed9fcbdb7aa7c14f2e76726aa5fdef028a5c10f5+∧ (   missing+        sha256:5dc1135d5481cfd6fde625aaed9fcbdb7aa7c14f2e76726aa5fdef028a5c10f5     ? ./core.dhall   )
dhall-lang/Prelude/JSON/render view
@@ -1,2 +1,3 @@-  ./render.dhall sha256:b5e5aee66b8fc018b50e1019a76340deafe5f8176854ea3611476d79990785da+  missing+    sha256:36befdd8bb5a1c2b372709da245a8d074533b86429e137b894c08ad16fa34836 ? ./render.dhall
dhall-lang/Prelude/JSON/render.dhall view
@@ -5,15 +5,18 @@ more sophisticated you should use `dhall-to-json` or `dhall-to-yaml` -} let JSON =-        ./core.dhall sha256:5dc1135d5481cfd6fde625aaed9fcbdb7aa7c14f2e76726aa5fdef028a5c10f5+        missing+          sha256:5dc1135d5481cfd6fde625aaed9fcbdb7aa7c14f2e76726aa5fdef028a5c10f5       ? ./core.dhall  let renderAs =-        ./renderAs.dhall sha256:5576473c02bc447d40d08bf103aaeca9637c1040367fdf07ff70032ba3e28043+        missing+          sha256:c23be039c9601a33d6546fd99a8d72bee8dde5f46176d57cc96613b31a3bb471       ? ./renderAs.dhall  let Format =-        ./Format.dhall sha256:d7936b510cfc091faa994652af0eb5feb889cd44bc989edbe4f1eb8c5623caac+        missing+          sha256:d7936b510cfc091faa994652af0eb5feb889cd44bc989edbe4f1eb8c5623caac       ? ./Format.dhall  let render
dhall-lang/Prelude/JSON/renderAs view
@@ -1,2 +1,3 @@-  ./renderAs.dhall sha256:5576473c02bc447d40d08bf103aaeca9637c1040367fdf07ff70032ba3e28043+  missing+    sha256:c23be039c9601a33d6546fd99a8d72bee8dde5f46176d57cc96613b31a3bb471 ? ./renderAs.dhall
dhall-lang/Prelude/JSON/renderAs.dhall view
@@ -1,33 +1,49 @@ --| Render a `JSON` value as `Text` in either JSON or YAML format.- let JSON =-        ./core.dhall sha256:5dc1135d5481cfd6fde625aaed9fcbdb7aa7c14f2e76726aa5fdef028a5c10f5+        missing+          sha256:5dc1135d5481cfd6fde625aaed9fcbdb7aa7c14f2e76726aa5fdef028a5c10f5       ? ./core.dhall  let Function/identity =-        ../Function/identity.dhall sha256:f78b96792b459cb664f41c6119bd8897dd04353a3343521d436cd82ad71cb4d4+        missing+          sha256:f78b96792b459cb664f41c6119bd8897dd04353a3343521d436cd82ad71cb4d4       ? ../Function/identity.dhall  let Text/concatMap =-        ../Text/concatMap.dhall sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f+        missing+          sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f       ? ../Text/concatMap.dhall  let List/map =-        ../List/map.dhall sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680+        missing+          sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680       ? ../List/map.dhall -let List/concatMap =-        ../List/concatMap.dhall sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64-      ? ../List/concatMap.dhall+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ../NonEmpty/Type.dhall -let NonEmpty-    : Type → Type-    = λ(a : Type) → { head : a, tail : List a }+let NonEmpty/toList =+        missing+          sha256:0977fe14b77232a4451dcf409c43df4589c4b3cdde7b613aab8df183be1b53f5+      ? ../NonEmpty/toList.dhall -let NonEmpty/singleton-    : ∀(a : Type) → a → NonEmpty a-    = λ(a : Type) → λ(x : a) → { head = x, tail = [] : List a }+let NonEmpty/concat =+        missing+          sha256:6d55181938c06c6b806877028f6a241912e9c0935d9a10dd958775bf21e0f64d+      ? ../NonEmpty/concat.dhall +let NonEmpty/map =+        missing+          sha256:93d53afe874bb2eed946c21ca5ada3c9716b7d00e6d8edfaba6484cd9c5a00bd+      ? ../NonEmpty/map.dhall++let NonEmpty/singleton =+        missing+          sha256:c9197aabe97695f7ca66f7419bf172d806b2c915594a8fc0d2ff6495db496ff2+      ? ../NonEmpty/singleton.dhall+ let List/uncons     : ∀(a : Type) → List a → Optional (NonEmpty a)     = {- This version uses the `ls` argument only once to prevent cache blowups at the price@@ -54,28 +70,6 @@           )           (None (NonEmpty a)) -let NonEmpty/toList-    : ∀(a : Type) → NonEmpty a → List a-    = λ(a : Type) → λ(nonEmpty : NonEmpty a) → [ nonEmpty.head ] # nonEmpty.tail--let NonEmpty/concat-    : ∀(a : Type) → NonEmpty (NonEmpty a) → NonEmpty a-    = λ(a : Type) →-      λ(lss : NonEmpty (NonEmpty a)) →-        { head = lss.head.head-        , tail =-              lss.head.tail-            # List/concatMap (NonEmpty a) a (NonEmpty/toList a) lss.tail-        }--let NonEmpty/map-    : ∀(a : Type) → ∀(b : Type) → (a → b) → NonEmpty a → NonEmpty b-    = λ(a : Type) →-      λ(b : Type) →-      λ(fn : a → b) →-      λ(ls : NonEmpty a) →-        { head = fn ls.head, tail = List/map a b fn ls.tail }- let NonEmpty/mapHead     : ∀(a : Type) → (a → a) → NonEmpty a → NonEmpty a     = λ(a : Type) →@@ -190,11 +184,28 @@ let indentTail = NonEmpty/mapTail Text addIndent  let Format =-        ./Format.dhall sha256:d7936b510cfc091faa994652af0eb5feb889cd44bc989edbe4f1eb8c5623caac+        missing+          sha256:d7936b510cfc091faa994652af0eb5feb889cd44bc989edbe4f1eb8c5623caac       ? ./Format.dhall  let ObjectField = { mapKey : Text, mapValue : Block } +let -- Essentially the same thing as `Text/show`, except that this does not+    -- escape `$`+    escape =+      List/fold+        (Text → Text)+        [ Text/replace "\"" "\\\""+        , Text/replace "\b" "\\b"+        , Text/replace "\f" "\\f"+        , Text/replace "\n" "\\n"+        , Text/replace "\r" "\\r"+        , Text/replace "\t" "\\t"+        , Text/replace "\\" "\\\\"+        ]+        Text+        (λ(replace : Text → Text) → λ(text : Text) → replace text)+ let renderJSONStruct =       λ(prefix : Text) →       λ(suffix : Text) →@@ -225,7 +236,7 @@ let renderObject =       λ(format : Format) →       λ(fields : NonEmpty ObjectField) →-        let keystr = λ(field : ObjectField) → "${Text/show field.mapKey}:"+        let keystr = λ(field : ObjectField) → "\"${escape field.mapKey}\":"          let prefixKeyOnFirst =               λ(field : ObjectField) →@@ -294,7 +305,7 @@         blockToText           ( json               Block-              { string = λ(x : Text) → Block.Simple (Text/show x)+              { string = λ(x : Text) → Block.Simple "\"${escape x}\""               , double = λ(x : Double) → Block.Simple (Double/show x)               , integer = λ(x : Integer) → Block.Simple (JSON.renderInteger x)               , object = manyBlocks ObjectField "{}" (renderObject format)@@ -424,5 +435,24 @@                 ''        in  True++let example3 =+      let specialCharacters =+            ''+            "\${"\b\f"}+            ${"\r"}	$''++      let data =+            JSON.object+              [ { mapKey = specialCharacters+                , mapValue = JSON.string specialCharacters+                }+              ]++      in    assert+          :   renderAs Format.JSON data+            ≡ ''+              { "\"\\\b\f\n\r\t$": "\"\\\b\f\n\r\t$" }+              ''  in  renderAs
+ dhall-lang/Prelude/JSON/renderCompact.dhall view
@@ -0,0 +1,61 @@+--| This renders JSON on a single line+let JSON =+        missing+          sha256:5dc1135d5481cfd6fde625aaed9fcbdb7aa7c14f2e76726aa5fdef028a5c10f5+      ? ./core.dhall++let Text/concatMapSep =+        missing+          sha256:c272aca80a607bc5963d1fcb38819e7e0d3e72ac4d02b1183b1afb6a91340840+      ? ../Text/concatMapSep++let renderInteger =+        missing+          sha256:15b8d2ae46d5002832741927af787761df49798c911e2bf85db7a7b9cb5c078c+      ? ./renderInteger.dhall++let renderCompact+    : JSON.Type → Text+    = λ(j : JSON.Type) →+        j+          Text+          { string = Text/show+          , double = Double/show+          , integer = renderInteger+          , object =+              λ(x : List { mapKey : Text, mapValue : Text }) →+                let body =+                      Text/concatMapSep+                        ","+                        { mapKey : Text, mapValue : Text }+                        ( λ(e : { mapKey : Text, mapValue : Text }) →+                            " ${Text/show e.mapKey}: ${e.mapValue}"+                        )+                        x++                in  "{${body} }"+          , array =+              λ(x : List Text) →+                let body = Text/concatMapSep "," Text (λ(y : Text) → " ${y}") x++                in  "[${body} ]"+          , bool = λ(x : Bool) → if x then "true" else "false"+          , null = "null"+          }++let example =+        assert+      :   renderCompact+            ( JSON.array+                [ JSON.bool True+                , JSON.string "Hello"+                , JSON.object+                    [ { mapKey = "foo", mapValue = JSON.null }+                    , { mapKey = "bar", mapValue = JSON.double 1.1 }+                    , { mapKey = "baz", mapValue = JSON.integer +2 }+                    ]+                ]+            )+        ≡ "[ true, \"Hello\", { \"foo\": null, \"bar\": 1.1, \"baz\": 2 } ]"++in  renderCompact
dhall-lang/Prelude/JSON/renderInteger.dhall view
@@ -2,9 +2,9 @@ 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 =-        ../Integer/nonNegative.dhall sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663+        missing+          sha256:b463373f070df6b1c8c7082051e0810fee38b360bab35256187c8c2b6af5c663       ? ../Integer/nonNegative.dhall  let renderInteger
dhall-lang/Prelude/JSON/renderYAML view
@@ -1,2 +1,3 @@-  ./renderYAML.dhall sha256:dad92a120956ae852be7496d1e1955bbf3f60834ab2ad32641269098f2846477+  missing+    sha256:bc71449397bbf48103c3ebbdd570cd27313115e94b2b1b96761d257d5c02d478 ? ./renderYAML.dhall
dhall-lang/Prelude/JSON/renderYAML.dhall view
@@ -8,17 +8,19 @@ For anything more sophisticated you should use `dhall-to-json` or `dhall-to-yaml`. -}- let JSON =-        ./core.dhall sha256:5dc1135d5481cfd6fde625aaed9fcbdb7aa7c14f2e76726aa5fdef028a5c10f5+        missing+          sha256:5dc1135d5481cfd6fde625aaed9fcbdb7aa7c14f2e76726aa5fdef028a5c10f5       ? ./core.dhall  let renderAs =-        ./renderAs.dhall sha256:5576473c02bc447d40d08bf103aaeca9637c1040367fdf07ff70032ba3e28043+        missing+          sha256:c23be039c9601a33d6546fd99a8d72bee8dde5f46176d57cc96613b31a3bb471       ? ./renderAs.dhall  let Format =-        ./Format.dhall sha256:d7936b510cfc091faa994652af0eb5feb889cd44bc989edbe4f1eb8c5623caac+        missing+          sha256:d7936b510cfc091faa994652af0eb5feb889cd44bc989edbe4f1eb8c5623caac       ? ./Format.dhall  let renderYAML
dhall-lang/Prelude/JSON/string view
@@ -1,2 +1,3 @@-  ./string.dhall sha256:7ddb3a3b9f3ed09ed011d621a10ad9825185cd03503be98a81d42f6afb77940e+  missing+    sha256:7ddb3a3b9f3ed09ed011d621a10ad9825185cd03503be98a81d42f6afb77940e ? ./string.dhall
dhall-lang/Prelude/JSON/string.dhall view
@@ -12,7 +12,8 @@ ``` -} let JSON =-        ./Type.dhall sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759+        missing+          sha256:40edbc9371979426df63e064333b02689b969c4cfbbccfa481216d2d1a6e9759       ? ./Type.dhall  let string
dhall-lang/Prelude/JSON/tagInline view
@@ -1,2 +1,3 @@-  ./tagInline.dhall sha256:49559ac11906ba6cc9eac25753e31e7addb13bc760df108024174c55523984c4+  missing+    sha256:49559ac11906ba6cc9eac25753e31e7addb13bc760df108024174c55523984c4 ? ./tagInline.dhall
dhall-lang/Prelude/JSON/tagInline.dhall view
@@ -1,10 +1,12 @@ --| Prepare a union value for JSON- or YAML-encoding with the inline layout let Nesting =-        ./Nesting.dhall sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335+        missing+          sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335       ? ./Nesting.dhall  let Tagged =-        ./Tagged.dhall sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194+        missing+          sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194       ? ./Tagged.dhall  let tagInline
dhall-lang/Prelude/JSON/tagNested view
@@ -1,2 +1,3 @@-  ./tagNested.dhall sha256:93a7415853b7677c832246efadc8e880c1b641a23589286a836a384ca311d26f+  missing+    sha256:93a7415853b7677c832246efadc8e880c1b641a23589286a836a384ca311d26f ? ./tagNested.dhall
dhall-lang/Prelude/JSON/tagNested.dhall view
@@ -1,10 +1,12 @@ --| Prepare a union value for JSON- or YAML-encoding with the nested layout let Nesting =-        ./Nesting.dhall sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335+        missing+          sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335       ? ./Nesting.dhall  let Tagged =-        ./Tagged.dhall sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194+        missing+          sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194       ? ./Tagged.dhall  let tagNested
dhall-lang/Prelude/List/all view
@@ -1,2 +1,3 @@-  ./all.dhall sha256:7ac5bb6f77e9ffe9e2356d90968d39764a9a32f75980206e6b12f815bb83dd15+  missing+    sha256:7ac5bb6f77e9ffe9e2356d90968d39764a9a32f75980206e6b12f815bb83dd15 ? ./all.dhall
dhall-lang/Prelude/List/any view
@@ -1,2 +1,3 @@-  ./any.dhall sha256:b8e9e13b25e799f342a81f6eda4075906eb1a19dfdcb10a0ca25925eba4033b8+  missing+    sha256:b8e9e13b25e799f342a81f6eda4075906eb1a19dfdcb10a0ca25925eba4033b8 ? ./any.dhall
dhall-lang/Prelude/List/build view
@@ -1,2 +1,3 @@-  ./build.dhall sha256:8cf73fc1e115cfcb79bb9cd490bfcbd45c824e93c57a0e64c86c0c72e9ebbe42+  missing+    sha256:8cf73fc1e115cfcb79bb9cd490bfcbd45c824e93c57a0e64c86c0c72e9ebbe42 ? ./build.dhall
dhall-lang/Prelude/List/concat view
@@ -1,2 +1,3 @@-  ./concat.dhall sha256:54e43278be13276e03bd1afa89e562e94a0a006377ebea7db14c7562b0de292b+  missing+    sha256:54e43278be13276e03bd1afa89e562e94a0a006377ebea7db14c7562b0de292b ? ./concat.dhall
dhall-lang/Prelude/List/concatMap view
@@ -1,2 +1,3 @@-  ./concatMap.dhall sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64+  missing+    sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64 ? ./concatMap.dhall
dhall-lang/Prelude/List/default view
@@ -1,2 +1,3 @@-  ./default.dhall sha256:fd77809e497227403f42848ffcda05a3efab442d961027c34f3e31d5d24e6379+  missing+    sha256:fd77809e497227403f42848ffcda05a3efab442d961027c34f3e31d5d24e6379 ? ./default.dhall
dhall-lang/Prelude/List/drop view
@@ -1,2 +1,3 @@-  ./drop.dhall sha256:af983ba3ead494dd72beed05c0f3a17c36a4244adedf7ced502c6512196ed0cf+  missing+    sha256:af983ba3ead494dd72beed05c0f3a17c36a4244adedf7ced502c6512196ed0cf ? ./drop.dhall
dhall-lang/Prelude/List/drop.dhall view
@@ -1,6 +1,7 @@ --| Remove first `n` elements of a list let Natural/greaterThanEqual =-        ../Natural/greaterThanEqual.dhall sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4+        missing+          sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4       ? ../Natural/greaterThanEqual.dhall  let drop
dhall-lang/Prelude/List/empty view
@@ -1,2 +1,3 @@-  ./empty.dhall sha256:b2f561f35098c457353723c93a22bd5de28d26ecc5370814bef9dfda421e0147+  missing+    sha256:b2f561f35098c457353723c93a22bd5de28d26ecc5370814bef9dfda421e0147 ? ./empty.dhall
dhall-lang/Prelude/List/filter view
@@ -1,2 +1,3 @@-  ./filter.dhall sha256:8ebfede5bbfe09675f246c33eb83964880ac615c4b1be8d856076fdbc4b26ba6+  missing+    sha256:8ebfede5bbfe09675f246c33eb83964880ac615c4b1be8d856076fdbc4b26ba6 ? ./filter.dhall
+ dhall-lang/Prelude/List/filterMap.dhall view
@@ -0,0 +1,45 @@+--| Transform a list by applying a function to each element and omitting None results.+let List/concatMap =+        missing+          sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64+      ? ./concatMap.dhall++let Optional/toList =+        missing+          sha256:d78f160c619119ef12389e48a629ce293d69f7624c8d016b7a4767ab400344c4+      ? ../Optional/toList.dhall++let filterMap+    : ∀(a : Type) → ∀(b : Type) → (a → Optional b) → List a → List b+    = λ(a : Type) →+      λ(b : Type) →+      λ(f : a → Optional b) →+        List/concatMap a b (λ(x : a) → Optional/toList b (f x))++let example0 =+        assert+      :   filterMap+            (List Natural)+            Natural+            (List/head Natural)+            [ [ 1 ], [] : List Natural, [ 3, 4 ] ]+        ≡ [ 1, 3 ]++let example1 =+      let Example = < Left : Bool | Right : Natural >++      in    assert+          :   filterMap+                Example+                Natural+                ( λ(x : Example) →+                    merge+                      { Left = λ(_ : Bool) → None Natural+                      , Right = λ(n : Natural) → Some n+                      }+                      x+                )+                [ Example.Left False, Example.Right 2, Example.Left True ]+            ≡ [ 2 ]++in  filterMap
dhall-lang/Prelude/List/fold view
@@ -1,2 +1,3 @@-  ./fold.dhall sha256:10bb945c25ab3943bd9df5a32e633cbfae112b7d3af38591784687e436a8d814+  missing+    sha256:10bb945c25ab3943bd9df5a32e633cbfae112b7d3af38591784687e436a8d814 ? ./fold.dhall
dhall-lang/Prelude/List/fold.dhall view
@@ -18,34 +18,26 @@       :   fold             Natural             [ 2, 3, 5 ]-            Natural-            (λ(x : Natural) → λ(y : Natural) → x + y)-            0-        ≡ 10+            Text+            (λ(x : Natural) → λ(y : Text) → Natural/show x ++ y)+            "0"+        ≡ "2350"  let example1 =-        assert-      :   ( λ(nil : Natural) →-              fold-                Natural-                [ 2, 3, 5 ]-                Natural-                (λ(x : Natural) → λ(y : Natural) → x + y)-                nil-          )-        ≡ (λ(nil : Natural) → 2 + (3 + (5 + nil)))+      λ(nil : Text) →+          assert+        :   fold+              Natural+              [ 2, 3, 5 ]+              Text+              (λ(x : Natural) → λ(y : Text) → Natural/show x ++ y)+              nil+          ≡ "2" ++ ("3" ++ ("5" ++ nil))  let example2 =-        assert-      :   ( λ(list : Type) →-            λ(cons : Natural → list → list) →-            λ(nil : list) →-              fold Natural [ 2, 3, 5 ] list cons nil-          )-        ≡ ( λ(list : Type) →-            λ(cons : Natural → list → list) →-            λ(nil : list) →-              cons 2 (cons 3 (cons 5 nil))-          )+      λ(cons : Natural → Text → Text) →+      λ(nil : Text) →+          assert+        : fold Natural [ 2, 3, 5 ] Text cons nil ≡ cons 2 (cons 3 (cons 5 nil))  in  fold
+ dhall-lang/Prelude/List/foldLeft.dhall view
@@ -0,0 +1,60 @@+{-|+`foldLeft` is like `List/fold` except that the accumulation starts from the left++If you treat the list `[ x, y, z ]` as `cons (cons (cons nil x) y) z`, then+`foldLeft` just replaces each `cons` and `nil` with something else+-}+let foldLeft+    : ∀(a : Type) →+      List a →+      ∀(list : Type) →+      ∀(cons : list → a → list) →+      ∀(nil : list) →+        list+    = λ(a : Type) →+      λ(xs : List a) →+      λ(list : Type) →+      λ(cons : list → a → list) →+      λ(nil : list) →+        List/fold+          a+          xs+          (list → list)+          (λ(x : a) → λ(f : list → list) → λ(l : list) → f (cons l x))+          (λ(l : list) → l)+          nil++let example0 =+        assert+      :   foldLeft+            Natural+            [ 2, 3, 5 ]+            Text+            (λ(x : Text) → λ(y : Natural) → x ++ Natural/show y)+            "0"+        ≡ "0235"++let example1 =+        assert+      :   ( λ(nil : Text) →+              foldLeft+                Natural+                [ 2, 3, 5 ]+                Text+                (λ(x : Text) → λ(y : Natural) → x ++ Natural/show y)+                nil+          )+        ≡ (λ(nil : Text) → nil ++ "2" ++ "3" ++ "5")++let example2 =+        assert+      :   ( λ(cons : Text → Natural → Text) →+            λ(nil : Text) →+              foldLeft Natural [ 2, 3, 5 ] Text cons nil+          )+        ≡ ( λ(cons : Text → Natural → Text) →+            λ(nil : Text) →+              cons (cons (cons nil 2) 3) 5+          )++in  foldLeft
dhall-lang/Prelude/List/generate view
@@ -1,2 +1,3 @@-  ./generate.dhall sha256:78ff1ad96c08b88a8263eea7bc8381c078225cfcb759c496f792edb5a5e0b1a4+  missing+    sha256:78ff1ad96c08b88a8263eea7bc8381c078225cfcb759c496f792edb5a5e0b1a4 ? ./generate.dhall
dhall-lang/Prelude/List/head view
@@ -1,2 +1,3 @@-  ./head.dhall sha256:0d2e65ba0aea908377e46d22020dc3ad970284f4ee4eb8e6b8c51e53038c0026+  missing+    sha256:0d2e65ba0aea908377e46d22020dc3ad970284f4ee4eb8e6b8c51e53038c0026 ? ./head.dhall
dhall-lang/Prelude/List/index view
@@ -1,2 +1,3 @@-  ./index.dhall sha256:e657b55ecae4d899465c3032cb1a64c6aa6dc2aa3034204f3c15ce5c96c03e63+  missing+    sha256:e657b55ecae4d899465c3032cb1a64c6aa6dc2aa3034204f3c15ce5c96c03e63 ? ./index.dhall
dhall-lang/Prelude/List/index.dhall view
@@ -1,6 +1,7 @@ --| Retrieve an element from a `List` using its 0-based index let drop =-        ./drop.dhall sha256:af983ba3ead494dd72beed05c0f3a17c36a4244adedf7ced502c6512196ed0cf+        missing+          sha256:af983ba3ead494dd72beed05c0f3a17c36a4244adedf7ced502c6512196ed0cf       ? ./drop.dhall  let index
dhall-lang/Prelude/List/indexed view
@@ -1,2 +1,3 @@-  ./indexed.dhall sha256:58bb44457fa81adf26f5123c1b2e8bef0c5aa22dac5fa5ebdfb7da84563b027f+  missing+    sha256:58bb44457fa81adf26f5123c1b2e8bef0c5aa22dac5fa5ebdfb7da84563b027f ? ./indexed.dhall
dhall-lang/Prelude/List/iterate view
@@ -1,2 +1,3 @@-  ./iterate.dhall sha256:e4999ccce190a2e2a6ab9cb188e3af6c40df474087827153005293f11bfe1d26+  missing+    sha256:e4999ccce190a2e2a6ab9cb188e3af6c40df474087827153005293f11bfe1d26 ? ./iterate.dhall
dhall-lang/Prelude/List/last view
@@ -1,2 +1,3 @@-  ./last.dhall sha256:741226b741af152a1638491cdff7f3aa74baf080ada2e63429483f3d195a984d+  missing+    sha256:741226b741af152a1638491cdff7f3aa74baf080ada2e63429483f3d195a984d ? ./last.dhall
dhall-lang/Prelude/List/length view
@@ -1,2 +1,3 @@-  ./length.dhall sha256:42c6812c7a9e3c6e6fad88f77c5b3849503964e071cb784e22c38c888a401461+  missing+    sha256:42c6812c7a9e3c6e6fad88f77c5b3849503964e071cb784e22c38c888a401461 ? ./length.dhall
dhall-lang/Prelude/List/map view
@@ -1,2 +1,3 @@-  ./map.dhall sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680+  missing+    sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680 ? ./map.dhall
+ dhall-lang/Prelude/List/mapMaybe.dhall view
@@ -0,0 +1,37 @@+--| Apply a function across a list, keeping only the `Some` results.+let List/unpackOptionals =+        missing+          sha256:0cbaa920f429cf7fc3907f8a9143203fe948883913560e6e1043223e6b3d05e4+      ? ./unpackOptionals.dhall++let List/map =+        missing+          sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680+      ? ./map.dhall++let mapMaybe+    : ∀(a : Type) → ∀(b : Type) → (a → Optional b) → List a → List b+    = λ(a : Type) →+      λ(b : Type) →+      λ(f : a → Optional b) →+      λ(xs : List a) →+        List/unpackOptionals b (List/map a (Optional b) f xs)++let property =+      λ(a : Type) →+      λ(b : Type) →+      λ(f : a → Optional b) →+        assert : mapMaybe a b f ([] : List a) ≡ ([] : List b)++let example0 =+        assert+      :   mapMaybe+            Natural+            Text+            ( λ(n : Natural) →+                if Natural/isZero n then None Text else Some (Natural/show n)+            )+            [ 0, 1, 2, 3 ]+        ≡ [ "1", "2", "3" ]++in  mapMaybe
+ dhall-lang/Prelude/List/mapWithIndex.dhall view
@@ -0,0 +1,41 @@+--| Transform a list by applying a function to each element with its index+let List/map =+        missing+          sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680+      ? ./map.dhall++let List/mapWithIndex+    : ∀(a : Type) → ∀(b : Type) → (Natural → a → b) → List a → List b+    = λ(a : Type) →+      λ(b : Type) →+      λ(f : Natural → a → b) →+      λ(xs : List a) →+        List/map+          { index : Natural, value : a }+          b+          (λ(i : { index : Natural, value : a }) → f i.index i.value)+          (List/indexed a xs)++let List/empty =+        missing+          sha256:b2f561f35098c457353723c93a22bd5de28d26ecc5370814bef9dfda421e0147+      ? ./empty.dhall++let List/replicate =+        missing+          sha256:d4250b45278f2d692302489ac3e78280acb238d27541c837ce46911ff3baa347+      ? ./replicate.dhall++let example0 =+        assert+      :   List/mapWithIndex+            Text+            (List Text)+            ( λ(index : Natural) →+              λ(value : Text) →+                List/replicate index Text value+            )+            [ "A", "B", "C" ]+        ≡ [ List/empty Text, [ "B" ], [ "C", "C" ] ]++in  List/mapWithIndex
dhall-lang/Prelude/List/null view
@@ -1,2 +1,3 @@-  ./null.dhall sha256:2338e39637e9a50d66ae1482c0ed559bbcc11e9442bfca8f8c176bbcd9c4fc80+  missing+    sha256:2338e39637e9a50d66ae1482c0ed559bbcc11e9442bfca8f8c176bbcd9c4fc80 ? ./null.dhall
dhall-lang/Prelude/List/package.dhall view
@@ -1,82 +1,125 @@ { all =-      ./all.dhall sha256:7ac5bb6f77e9ffe9e2356d90968d39764a9a32f75980206e6b12f815bb83dd15+      missing+        sha256:7ac5bb6f77e9ffe9e2356d90968d39764a9a32f75980206e6b12f815bb83dd15     ? ./all.dhall , any =-      ./any.dhall sha256:b8e9e13b25e799f342a81f6eda4075906eb1a19dfdcb10a0ca25925eba4033b8+      missing+        sha256:b8e9e13b25e799f342a81f6eda4075906eb1a19dfdcb10a0ca25925eba4033b8     ? ./any.dhall , build =-      ./build.dhall sha256:8cf73fc1e115cfcb79bb9cd490bfcbd45c824e93c57a0e64c86c0c72e9ebbe42+      missing+        sha256:8cf73fc1e115cfcb79bb9cd490bfcbd45c824e93c57a0e64c86c0c72e9ebbe42     ? ./build.dhall , concat =-      ./concat.dhall sha256:54e43278be13276e03bd1afa89e562e94a0a006377ebea7db14c7562b0de292b+      missing+        sha256:54e43278be13276e03bd1afa89e562e94a0a006377ebea7db14c7562b0de292b     ? ./concat.dhall , concatMap =-      ./concatMap.dhall sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64+      missing+        sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64     ? ./concatMap.dhall , default =-      ./default.dhall sha256:fd77809e497227403f42848ffcda05a3efab442d961027c34f3e31d5d24e6379+      missing+        sha256:fd77809e497227403f42848ffcda05a3efab442d961027c34f3e31d5d24e6379     ? ./default.dhall , drop =-      ./drop.dhall sha256:af983ba3ead494dd72beed05c0f3a17c36a4244adedf7ced502c6512196ed0cf+      missing+        sha256:af983ba3ead494dd72beed05c0f3a17c36a4244adedf7ced502c6512196ed0cf     ? ./drop.dhall , empty =-      ./empty.dhall sha256:b2f561f35098c457353723c93a22bd5de28d26ecc5370814bef9dfda421e0147+      missing+        sha256:b2f561f35098c457353723c93a22bd5de28d26ecc5370814bef9dfda421e0147     ? ./empty.dhall , filter =-      ./filter.dhall sha256:8ebfede5bbfe09675f246c33eb83964880ac615c4b1be8d856076fdbc4b26ba6+      missing+        sha256:8ebfede5bbfe09675f246c33eb83964880ac615c4b1be8d856076fdbc4b26ba6     ? ./filter.dhall+, filterMap =+      missing+        sha256:94b7ed4204d1c79aaf55527ef51024e7085b8dd2896952cffbd12d8f95e16f46+    ? ./filterMap.dhall , fold =-      ./fold.dhall sha256:10bb945c25ab3943bd9df5a32e633cbfae112b7d3af38591784687e436a8d814+      missing+        sha256:10bb945c25ab3943bd9df5a32e633cbfae112b7d3af38591784687e436a8d814     ? ./fold.dhall+, foldLeft =+      missing+        sha256:3c6ab57950fe644906b7bbdef0b9523440b6ee17773ebb8cbd41ffacb8bfab61+    ? ./foldLeft.dhall , generate =-      ./generate.dhall sha256:78ff1ad96c08b88a8263eea7bc8381c078225cfcb759c496f792edb5a5e0b1a4+      missing+        sha256:78ff1ad96c08b88a8263eea7bc8381c078225cfcb759c496f792edb5a5e0b1a4     ? ./generate.dhall , head =-      ./head.dhall sha256:0d2e65ba0aea908377e46d22020dc3ad970284f4ee4eb8e6b8c51e53038c0026+      missing+        sha256:0d2e65ba0aea908377e46d22020dc3ad970284f4ee4eb8e6b8c51e53038c0026     ? ./head.dhall , index =-      ./index.dhall sha256:e657b55ecae4d899465c3032cb1a64c6aa6dc2aa3034204f3c15ce5c96c03e63+      missing+        sha256:e657b55ecae4d899465c3032cb1a64c6aa6dc2aa3034204f3c15ce5c96c03e63     ? ./index.dhall , indexed =-      ./indexed.dhall sha256:58bb44457fa81adf26f5123c1b2e8bef0c5aa22dac5fa5ebdfb7da84563b027f+      missing+        sha256:58bb44457fa81adf26f5123c1b2e8bef0c5aa22dac5fa5ebdfb7da84563b027f     ? ./indexed.dhall , iterate =-      ./iterate.dhall sha256:e4999ccce190a2e2a6ab9cb188e3af6c40df474087827153005293f11bfe1d26+      missing+        sha256:e4999ccce190a2e2a6ab9cb188e3af6c40df474087827153005293f11bfe1d26     ? ./iterate.dhall , last =-      ./last.dhall sha256:741226b741af152a1638491cdff7f3aa74baf080ada2e63429483f3d195a984d+      missing+        sha256:741226b741af152a1638491cdff7f3aa74baf080ada2e63429483f3d195a984d     ? ./last.dhall , length =-      ./length.dhall sha256:42c6812c7a9e3c6e6fad88f77c5b3849503964e071cb784e22c38c888a401461+      missing+        sha256:42c6812c7a9e3c6e6fad88f77c5b3849503964e071cb784e22c38c888a401461     ? ./length.dhall , map =-      ./map.dhall sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680+      missing+        sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680     ? ./map.dhall+, mapMaybe =+      missing+        sha256:6f3c4f8c94577b46e7d30f8df7e82a269b0ad0a7e18c0f0370f243fd1127e77f+    ? ./mapMaybe.dhall+, mapWithIndex =+      missing+        sha256:98599e0b55c5d3ae75264ba90657c6f68c7ce32834bd12b215acaea711eed6eb+    ? ./mapWithIndex.dhall , null =-      ./null.dhall sha256:2338e39637e9a50d66ae1482c0ed559bbcc11e9442bfca8f8c176bbcd9c4fc80+      missing+        sha256:2338e39637e9a50d66ae1482c0ed559bbcc11e9442bfca8f8c176bbcd9c4fc80     ? ./null.dhall , partition =-      ./partition.dhall sha256:38147ac6d750a6492736dd90cc967bf09aa405c499de943c64fab7b86ae02f03+      missing+        sha256:38147ac6d750a6492736dd90cc967bf09aa405c499de943c64fab7b86ae02f03     ? ./partition.dhall , replicate =-      ./replicate.dhall sha256:d4250b45278f2d692302489ac3e78280acb238d27541c837ce46911ff3baa347+      missing+        sha256:d4250b45278f2d692302489ac3e78280acb238d27541c837ce46911ff3baa347     ? ./replicate.dhall , reverse =-      ./reverse.dhall sha256:ad99d224d61852de6696da5a7d04c98dbe676fe67d5e4ef4f19e9aaa27006e9d+      missing+        sha256:ad99d224d61852de6696da5a7d04c98dbe676fe67d5e4ef4f19e9aaa27006e9d     ? ./reverse.dhall , shifted =-      ./shifted.dhall sha256:54fb22c7e952ebce1cfc0fcdd33ce4cfa817bff9d6564af268dea6685f8b5dfe+      missing+        sha256:54fb22c7e952ebce1cfc0fcdd33ce4cfa817bff9d6564af268dea6685f8b5dfe     ? ./shifted.dhall , take =-      ./take.dhall sha256:b3e08ee8c3a5bf3d8ccee6b2b2008fbb8e51e7373aef6f1af67ad10078c9fbfa+      missing+        sha256:b3e08ee8c3a5bf3d8ccee6b2b2008fbb8e51e7373aef6f1af67ad10078c9fbfa     ? ./take.dhall , unpackOptionals =-      ./unpackOptionals.dhall sha256:0cbaa920f429cf7fc3907f8a9143203fe948883913560e6e1043223e6b3d05e4+      missing+        sha256:0cbaa920f429cf7fc3907f8a9143203fe948883913560e6e1043223e6b3d05e4     ? ./unpackOptionals.dhall , unzip =-      ./unzip.dhall sha256:4d6003e9e683a289fe33f4c90f958eb1e08ea0bbb474210fcd90d1885c9660e9+      missing+        sha256:4d6003e9e683a289fe33f4c90f958eb1e08ea0bbb474210fcd90d1885c9660e9     ? ./unzip.dhall , zip =-      ./zip.dhall sha256:85ed955eabf3998767f4ad2a28e57d40cd4c68a95519d79e9b622f1d26d979da+      missing+        sha256:85ed955eabf3998767f4ad2a28e57d40cd4c68a95519d79e9b622f1d26d979da     ? ./zip.dhall }
dhall-lang/Prelude/List/partition view
@@ -1,2 +1,3 @@-  ./partition.dhall sha256:38147ac6d750a6492736dd90cc967bf09aa405c499de943c64fab7b86ae02f03+  missing+    sha256:38147ac6d750a6492736dd90cc967bf09aa405c499de943c64fab7b86ae02f03 ? ./partition.dhall
dhall-lang/Prelude/List/replicate view
@@ -1,2 +1,3 @@-  ./replicate.dhall sha256:d4250b45278f2d692302489ac3e78280acb238d27541c837ce46911ff3baa347+  missing+    sha256:d4250b45278f2d692302489ac3e78280acb238d27541c837ce46911ff3baa347 ? ./replicate.dhall
dhall-lang/Prelude/List/reverse view
@@ -1,2 +1,3 @@-  ./reverse.dhall sha256:ad99d224d61852de6696da5a7d04c98dbe676fe67d5e4ef4f19e9aaa27006e9d+  missing+    sha256:ad99d224d61852de6696da5a7d04c98dbe676fe67d5e4ef4f19e9aaa27006e9d ? ./reverse.dhall
dhall-lang/Prelude/List/shifted view
@@ -1,2 +1,3 @@-  ./shifted.dhall sha256:54fb22c7e952ebce1cfc0fcdd33ce4cfa817bff9d6564af268dea6685f8b5dfe+  missing+    sha256:54fb22c7e952ebce1cfc0fcdd33ce4cfa817bff9d6564af268dea6685f8b5dfe ? ./shifted.dhall
dhall-lang/Prelude/List/take view
@@ -1,2 +1,3 @@-  ./take.dhall sha256:b3e08ee8c3a5bf3d8ccee6b2b2008fbb8e51e7373aef6f1af67ad10078c9fbfa+  missing+    sha256:b3e08ee8c3a5bf3d8ccee6b2b2008fbb8e51e7373aef6f1af67ad10078c9fbfa ? ./take.dhall
dhall-lang/Prelude/List/take.dhall view
@@ -1,6 +1,7 @@ --| Truncate a list to the first `n` elements let Natural/lessThan =-        ../Natural/lessThan.dhall sha256:3381b66749290769badf8855d8a3f4af62e8de52d1364d838a9d1e20c94fa70c+        missing+          sha256:3381b66749290769badf8855d8a3f4af62e8de52d1364d838a9d1e20c94fa70c       ? ../Natural/lessThan.dhall  let take
dhall-lang/Prelude/List/unpackOptionals view
@@ -1,2 +1,3 @@-  ./unpackOptionals.dhall sha256:0cbaa920f429cf7fc3907f8a9143203fe948883913560e6e1043223e6b3d05e4+  missing+    sha256:0cbaa920f429cf7fc3907f8a9143203fe948883913560e6e1043223e6b3d05e4 ? ./unpackOptionals.dhall
dhall-lang/Prelude/List/unpackOptionals.dhall view
@@ -1,16 +1,12 @@ --| Unpack Optionals in a List, omitting None items.--let List/concatMap =-        ./concatMap.dhall sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64-      ? ./concatMap.dhall--let Optional/toList =-        ../Optional/toList.dhall sha256:d78f160c619119ef12389e48a629ce293d69f7624c8d016b7a4767ab400344c4-      ? ../Optional/toList.dhall+let List/filterMap =+        missing+          sha256:94b7ed4204d1c79aaf55527ef51024e7085b8dd2896952cffbd12d8f95e16f46+      ? ./filterMap.dhall  let unpackOptionals     : ∀(a : Type) → ∀(l : List (Optional a)) → List a-    = λ(a : Type) → List/concatMap (Optional a) a (Optional/toList a)+    = λ(a : Type) → List/filterMap (Optional a) a (λ(x : Optional a) → x)  let property1 =       λ(a : Type) → λ(x : a) → assert : unpackOptionals a [ Some x ] ≡ [ x ]
dhall-lang/Prelude/List/unzip view
@@ -1,2 +1,3 @@-  ./unzip.dhall sha256:4d6003e9e683a289fe33f4c90f958eb1e08ea0bbb474210fcd90d1885c9660e9+  missing+    sha256:4d6003e9e683a289fe33f4c90f958eb1e08ea0bbb474210fcd90d1885c9660e9 ? ./unzip.dhall
dhall-lang/Prelude/List/zip view
@@ -1,2 +1,3 @@-  ./zip.dhall sha256:85ed955eabf3998767f4ad2a28e57d40cd4c68a95519d79e9b622f1d26d979da+  missing+    sha256:85ed955eabf3998767f4ad2a28e57d40cd4c68a95519d79e9b622f1d26d979da ? ./zip.dhall
dhall-lang/Prelude/List/zip.dhall view
@@ -4,7 +4,8 @@ The resulting `List` will have the length of the shortest of its arguments. -} let List/index =-        ./index.dhall sha256:e657b55ecae4d899465c3032cb1a64c6aa6dc2aa3034204f3c15ce5c96c03e63+        missing+          sha256:e657b55ecae4d899465c3032cb1a64c6aa6dc2aa3034204f3c15ce5c96c03e63       ? ./index.dhall  let zip
dhall-lang/Prelude/Location/Type view
@@ -1,2 +1,3 @@-  ./Type.dhall sha256:613ebb491aeef4ff06368058b4f0e6e3bb8a58d8c145131fc0b947aac045a529+  missing+    sha256:613ebb491aeef4ff06368058b4f0e6e3bb8a58d8c145131fc0b947aac045a529 ? ./Type.dhall
dhall-lang/Prelude/Location/Type.dhall view
@@ -5,8 +5,7 @@  let example0 =         assert-      :     missing sha256:f428188ff9d77ea15bc2bcd0da3f8ed81b304e175b07ade42a3b0fb02941b2aa as Location-          ? missing as Location+      :   missing as Location         ≡ < Environment : Text           | Local : Text           | Missing
dhall-lang/Prelude/Location/package.dhall view
@@ -1,4 +1,5 @@ { Type =-      ./Type.dhall sha256:613ebb491aeef4ff06368058b4f0e6e3bb8a58d8c145131fc0b947aac045a529+      missing+        sha256:613ebb491aeef4ff06368058b4f0e6e3bb8a58d8c145131fc0b947aac045a529     ? ./Type.dhall }
dhall-lang/Prelude/Map/Entry view
@@ -1,2 +1,3 @@-  ./Entry.dhall sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346+  missing+    sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346 ? ./Entry.dhall
dhall-lang/Prelude/Map/Type view
@@ -1,2 +1,3 @@-  ./Type.dhall sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed+  missing+    sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed ? ./Type.dhall
dhall-lang/Prelude/Map/empty view
@@ -1,2 +1,3 @@-  ./empty.dhall sha256:4c612558b8bbe8f955550ed3fb295d57b1b864c85cd52615b52d0ee0e9682e52+  missing+    sha256:4c612558b8bbe8f955550ed3fb295d57b1b864c85cd52615b52d0ee0e9682e52 ? ./empty.dhall
dhall-lang/Prelude/Map/empty.dhall view
@@ -1,6 +1,7 @@ --| An empty `Map` of the given key and value types let Map =-        ./Type.dhall sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed+        missing+          sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed       ? ./Type.dhall  let empty
dhall-lang/Prelude/Map/keyText view
@@ -1,2 +1,3 @@-  ./keyText.dhall sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc+  missing+    sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc ? ./keyText.dhall
dhall-lang/Prelude/Map/keyValue view
@@ -1,2 +1,3 @@-  ./keyValue.dhall sha256:a0a97199d280c4cce72ffcbbf93b7ceda0a569cf4d173ac98e0aaaa78034b98c+  missing+    sha256:a0a97199d280c4cce72ffcbbf93b7ceda0a569cf4d173ac98e0aaaa78034b98c ? ./keyValue.dhall
dhall-lang/Prelude/Map/keys view
@@ -1,2 +1,3 @@-  ./keys.dhall sha256:d13ec34e6acf7c349d82272ef09a37c7bdf37f0dab489e9df47a1ff215d9f5e7+  missing+    sha256:d13ec34e6acf7c349d82272ef09a37c7bdf37f0dab489e9df47a1ff215d9f5e7 ? ./keys.dhall
dhall-lang/Prelude/Map/keys.dhall view
@@ -1,14 +1,17 @@ --| Get all of the keys of a `Map` as a `List` let Map =-        ./Type.dhall sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed+        missing+          sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed       ? ./Type.dhall  let Entry =-        ./Entry.dhall sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346+        missing+          sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346       ? ./Entry.dhall  let List/map =-        ../List/map sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680+        missing+          sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680       ? ../List/map  let keys
dhall-lang/Prelude/Map/map view
@@ -1,2 +1,3 @@-  ./map.dhall sha256:23e09b0b9f08649797dfe1ca39755d5e1c7cad2d0944bdd36c7a0bf804bde8d0+  missing+    sha256:23e09b0b9f08649797dfe1ca39755d5e1c7cad2d0944bdd36c7a0bf804bde8d0 ? ./map.dhall
dhall-lang/Prelude/Map/map.dhall view
@@ -1,14 +1,17 @@ --| Transform a `Map` by applying a function to each value let Map =-        ./Type.dhall sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed+        missing+          sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed       ? ./Type.dhall  let Entry =-        ./Entry.dhall sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346+        missing+          sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346       ? ./Entry.dhall  let List/map =-        ../List/map.dhall sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680+        missing+          sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680       ? ../List/map.dhall  let map
+ dhall-lang/Prelude/Map/mapMaybe.dhall view
@@ -0,0 +1,56 @@+--| Apply a function across the values of a `Map k v`, dropping+--  entries whose values return `None`.+let Map/empty =+        missing+          sha256:4c612558b8bbe8f955550ed3fb295d57b1b864c85cd52615b52d0ee0e9682e52+      ? ./empty.dhall++let Map/unpackOptionals =+        missing+          sha256:66c3e6f6f81418cf99342e1dba739617c01af4b27c1ca5e2e1d7bce64a522e22+      ? ./unpackOptionals.dhall++let Map/map =+        missing+          sha256:23e09b0b9f08649797dfe1ca39755d5e1c7cad2d0944bdd36c7a0bf804bde8d0+      ? ./map.dhall++let Map/Type =+        missing+          sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed+      ? ./Type.dhall++let mapMaybe+    : ∀(k : Type) →+      ∀(a : Type) →+      ∀(b : Type) →+      (a → Optional b) →+      Map/Type k a →+        Map/Type k b+    = λ(k : Type) →+      λ(a : Type) →+      λ(b : Type) →+      λ(f : a → Optional b) →+      λ(m : Map/Type k a) →+        Map/unpackOptionals k b (Map/map k a (Optional b) f m)++let property =+      λ(k : Type) →+      λ(a : Type) →+      λ(b : Type) →+      λ(f : a → Optional b) →+        assert : mapMaybe k a b f (Map/empty k a) ≡ Map/empty k b++let example0 =+        assert+      :   mapMaybe+            Text+            Natural+            Text+            ( λ(n : Natural) →+                if Natural/isZero n then None Text else Some (Natural/show n)+            )+            (toMap { foo = 2, bar = 0 })+        ≡ toMap { foo = "2" }++in  mapMaybe
dhall-lang/Prelude/Map/package.dhall view
@@ -1,28 +1,41 @@ { Type =-      ./Type sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed+      missing+        sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed     ? ./Type , Entry =-      ./Entry sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346+      missing+        sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346     ? ./Entry , empty =-      ./empty sha256:4c612558b8bbe8f955550ed3fb295d57b1b864c85cd52615b52d0ee0e9682e52+      missing+        sha256:4c612558b8bbe8f955550ed3fb295d57b1b864c85cd52615b52d0ee0e9682e52     ? ./empty , keyText =-      ./keyText sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc+      missing+        sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc     ? ./keyText , keyValue =-      ./keyValue sha256:a0a97199d280c4cce72ffcbbf93b7ceda0a569cf4d173ac98e0aaaa78034b98c+      missing+        sha256:a0a97199d280c4cce72ffcbbf93b7ceda0a569cf4d173ac98e0aaaa78034b98c     ? ./keyValue , keys =-      ./keys sha256:d13ec34e6acf7c349d82272ef09a37c7bdf37f0dab489e9df47a1ff215d9f5e7+      missing+        sha256:d13ec34e6acf7c349d82272ef09a37c7bdf37f0dab489e9df47a1ff215d9f5e7     ? ./keys , map =-      ./map sha256:23e09b0b9f08649797dfe1ca39755d5e1c7cad2d0944bdd36c7a0bf804bde8d0+      missing+        sha256:23e09b0b9f08649797dfe1ca39755d5e1c7cad2d0944bdd36c7a0bf804bde8d0     ? ./map+, mapMaybe =+      missing+        sha256:4ea58b720d7af38cef3ef07bef36e476caeed21032cd4a9dc733868a74d9a521+    ? ./mapMaybe.dhall , unpackOptionals =-      ./unpackOptionals.dhall sha256:66c3e6f6f81418cf99342e1dba739617c01af4b27c1ca5e2e1d7bce64a522e22+      missing+        sha256:66c3e6f6f81418cf99342e1dba739617c01af4b27c1ca5e2e1d7bce64a522e22     ? ./unpackOptionals.dhall , values =-      ./values sha256:ae02cfb06a9307cbecc06130e84fd0c7b96b7f1f11648961e1b030ec00940be8+      missing+        sha256:ae02cfb06a9307cbecc06130e84fd0c7b96b7f1f11648961e1b030ec00940be8     ? ./values }
dhall-lang/Prelude/Map/unpackOptionals.dhall view
@@ -1,16 +1,18 @@ --| Turn a `Map k (Optional v)` into a `Map k v` by dropping all --  entries with value `None`.- let List/concatMap =-        ../List/concatMap.dhall sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64+        missing+          sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64       ? ../List/concatMap.dhall  let Map/Entry =-        ./Entry.dhall sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346+        missing+          sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346       ? ./Entry.dhall  let Map/Type =-        ./Type.dhall sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed+        missing+          sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed       ? ./Type.dhall  let unpackOptionals
dhall-lang/Prelude/Map/values view
@@ -1,2 +1,3 @@-  ./values.dhall sha256:ae02cfb06a9307cbecc06130e84fd0c7b96b7f1f11648961e1b030ec00940be8+  missing+    sha256:ae02cfb06a9307cbecc06130e84fd0c7b96b7f1f11648961e1b030ec00940be8 ? ./values.dhall
dhall-lang/Prelude/Map/values.dhall view
@@ -1,14 +1,17 @@ --| Get all of the values of a `Map` as a `List` let Map =-        ./Type.dhall sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed+        missing+          sha256:210c7a9eba71efbb0f7a66b3dcf8b9d3976ffc2bc0e907aadfb6aa29c333e8ed       ? ./Type.dhall  let Entry =-        ./Entry.dhall sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346+        missing+          sha256:f334283bdd9cd88e6ea510ca914bc221fc2dab5fb424d24514b2e0df600d5346       ? ./Entry.dhall  let List/map =-        ../List/map.dhall sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680+        missing+          sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680       ? ../List/map.dhall  let values
dhall-lang/Prelude/Monoid view
@@ -1,2 +1,3 @@-  ./Monoid.dhall sha256:26fafa098600ef7a54ef9dba5ada416bbbdd21df1af306c052420c61553ad4af+  missing+    sha256:26fafa098600ef7a54ef9dba5ada416bbbdd21df1af306c052420c61553ad4af ? ./Monoid.dhall
dhall-lang/Prelude/Natural/build view
@@ -1,2 +1,3 @@-  ./build.dhall sha256:e7e25e6c4f1d8e573606ed1bef725396ac2de5c68f7c5d329ffc5822085b984c+  missing+    sha256:e7e25e6c4f1d8e573606ed1bef725396ac2de5c68f7c5d329ffc5822085b984c ? ./build.dhall
dhall-lang/Prelude/Natural/enumerate view
@@ -1,2 +1,3 @@-  ./enumerate.dhall sha256:0cf083980a752b21ce0df9fc2222a4c139f50909e2353576e26a191002aa1ce3+  missing+    sha256:0cf083980a752b21ce0df9fc2222a4c139f50909e2353576e26a191002aa1ce3 ? ./enumerate.dhall
dhall-lang/Prelude/Natural/equal view
@@ -1,2 +1,3 @@-  ./equal.dhall sha256:7f108edfa35ddc7cebafb24dc073478e93a802e13b5bc3fd22f4768c9b066e60+  missing+    sha256:7f108edfa35ddc7cebafb24dc073478e93a802e13b5bc3fd22f4768c9b066e60 ? ./equal.dhall
dhall-lang/Prelude/Natural/equal.dhall view
@@ -1,6 +1,7 @@ --| `equal` checks if two Naturals are equal. let lessThanEqual =-        ./lessThanEqual.dhall sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99+        missing+          sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99       ? ./lessThanEqual.dhall  let equal
dhall-lang/Prelude/Natural/even view
@@ -1,2 +1,3 @@-  ./even.dhall sha256:b85b8b56892dfef881e1c0e79eade0b949528f792aac0ea42432b315ede4ee66+  missing+    sha256:b85b8b56892dfef881e1c0e79eade0b949528f792aac0ea42432b315ede4ee66 ? ./even.dhall
dhall-lang/Prelude/Natural/fold view
@@ -1,2 +1,3 @@-  ./fold.dhall sha256:fd01c931e585a8f5fd049af7b076b862ea164f1813b34800c7616a49e549ee06+  missing+    sha256:fd01c931e585a8f5fd049af7b076b862ea164f1813b34800c7616a49e549ee06 ? ./fold.dhall
dhall-lang/Prelude/Natural/fold.dhall view
@@ -12,24 +12,17 @@         natural     = Natural/fold -let example0 = assert : fold 3 Natural (λ(x : Natural) → 5 * x) 1 ≡ 125+let example0 = assert : fold 3 Text (λ(x : Text) → "A" ++ x) "B" ≡ "AAAB"  let example1 =-        assert-      :   (λ(zero : Natural) → fold 3 Natural (λ(x : Natural) → 5 * x) zero)-        ≡ (λ(zero : Natural) → 5 * (5 * (5 * zero)))+      λ(zero : Text) →+          assert+        :   fold 3 Text (λ(x : Text) → "A" ++ x) zero+          ≡ "A" ++ ("A" ++ ("A" ++ zero))  let example2 =-        assert-      :   ( λ(natural : Type) →-            λ(succ : natural → natural) →-            λ(zero : natural) →-              fold 3 natural succ zero-          )-        ≡ ( λ(natural : Type) →-            λ(succ : natural → natural) →-            λ(zero : natural) →-              succ (succ (succ zero))-          )+      λ(succ : Text → Text) →+      λ(zero : Text) →+        assert : fold 3 Text succ zero ≡ succ (succ (succ zero))  in  fold
dhall-lang/Prelude/Natural/greaterThan view
@@ -1,2 +1,3 @@-  ./greaterThan.dhall sha256:f702abcdfcd7ad73619b9285d7e41c3a1d017fb6b8d037cf40bd93bf30c09b2c+  missing+    sha256:f702abcdfcd7ad73619b9285d7e41c3a1d017fb6b8d037cf40bd93bf30c09b2c ? ./greaterThan.dhall
dhall-lang/Prelude/Natural/greaterThan.dhall view
@@ -1,6 +1,7 @@ --| `greaterThan` checks if one Natural is strictly greater than another. let lessThan =-        ./lessThan.dhall sha256:3381b66749290769badf8855d8a3f4af62e8de52d1364d838a9d1e20c94fa70c+        missing+          sha256:3381b66749290769badf8855d8a3f4af62e8de52d1364d838a9d1e20c94fa70c       ? ./lessThan.dhall  let greaterThan
dhall-lang/Prelude/Natural/greaterThanEqual view
@@ -1,2 +1,3 @@-  ./greaterThanEqual.dhall sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4+  missing+    sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4 ? ./greaterThanEqual.dhall
dhall-lang/Prelude/Natural/greaterThanEqual.dhall view
@@ -2,7 +2,8 @@ `greaterThanEqual` checks if one Natural is greater than or equal to another. -} let lessThanEqual =-        ./lessThanEqual.dhall sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99+        missing+          sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99       ? ./lessThanEqual.dhall  let greaterThanEqual
dhall-lang/Prelude/Natural/isZero view
@@ -1,2 +1,3 @@-  ./isZero.dhall sha256:1be98236800ed2d5cff44f16ca02b34b0c37dfa239d9e0d63d9d2c6eeae3d1d1+  missing+    sha256:1be98236800ed2d5cff44f16ca02b34b0c37dfa239d9e0d63d9d2c6eeae3d1d1 ? ./isZero.dhall
dhall-lang/Prelude/Natural/lessThan view
@@ -1,2 +1,3 @@-  ./lessThan.dhall sha256:3381b66749290769badf8855d8a3f4af62e8de52d1364d838a9d1e20c94fa70c+  missing+    sha256:3381b66749290769badf8855d8a3f4af62e8de52d1364d838a9d1e20c94fa70c ? ./lessThan.dhall
dhall-lang/Prelude/Natural/lessThan.dhall view
@@ -1,10 +1,12 @@ --| `lessThan` checks if one Natural is strictly less than another. let greaterThanEqual =-        ./greaterThanEqual.dhall sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4+        missing+          sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4       ? ./greaterThanEqual.dhall  let Bool/not =-        ../Bool/not.dhall sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4+        missing+          sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4       ? ../Bool/not.dhall  let lessThan
dhall-lang/Prelude/Natural/lessThanEqual view
@@ -1,2 +1,3 @@-  ./lessThanEqual.dhall sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99+  missing+    sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99 ? ./lessThanEqual.dhall
dhall-lang/Prelude/Natural/listMax view
@@ -1,2 +1,3 @@-  ./listMax.dhall sha256:20906ffcc9970f740106d4516cb7868b43d75ff8c9f00ff8a9680ae68c48a472+  missing+    sha256:20906ffcc9970f740106d4516cb7868b43d75ff8c9f00ff8a9680ae68c48a472 ? ./listMax.dhall
dhall-lang/Prelude/Natural/listMax.dhall view
@@ -3,11 +3,13 @@ `List` is empty -} let max =-        ./max.dhall sha256:1f3b18da330223ab039fad11693da72c7e68d516f50502c73f41a89a097b62f7+        missing+          sha256:1f3b18da330223ab039fad11693da72c7e68d516f50502c73f41a89a097b62f7       ? ./max.dhall  let Optional/map =-        ../Optional/map.dhall sha256:501534192d988218d43261c299cc1d1e0b13d25df388937add784778ab0054fa+        missing+          sha256:501534192d988218d43261c299cc1d1e0b13d25df388937add784778ab0054fa       ? ../Optional/map.dhall  let listMax
dhall-lang/Prelude/Natural/listMin view
@@ -1,2 +1,3 @@-  ./listMin.dhall sha256:ee70b0d010bbca6012162e8ae1f6e9d9bd10a152675509b0f23145b98b5d43c6+  missing+    sha256:ee70b0d010bbca6012162e8ae1f6e9d9bd10a152675509b0f23145b98b5d43c6 ? ./listMin.dhall
dhall-lang/Prelude/Natural/listMin.dhall view
@@ -3,11 +3,13 @@ `List` is empty -} let min =-        ./min.dhall sha256:f25f9c462e4dbf0eb15f9ff6ac840c6e9c82255a7f4f2ab408bdab338e028710+        missing+          sha256:f25f9c462e4dbf0eb15f9ff6ac840c6e9c82255a7f4f2ab408bdab338e028710       ? ./min.dhall  let Optional/map =-        ../Optional/map.dhall sha256:501534192d988218d43261c299cc1d1e0b13d25df388937add784778ab0054fa+        missing+          sha256:501534192d988218d43261c299cc1d1e0b13d25df388937add784778ab0054fa       ? ../Optional/map.dhall  let listMin
dhall-lang/Prelude/Natural/max view
@@ -1,2 +1,3 @@-  ./max.dhall sha256:1f3b18da330223ab039fad11693da72c7e68d516f50502c73f41a89a097b62f7+  missing+    sha256:1f3b18da330223ab039fad11693da72c7e68d516f50502c73f41a89a097b62f7 ? ./max.dhall
dhall-lang/Prelude/Natural/max.dhall view
@@ -1,6 +1,7 @@ --| `max a b` returns the larger of `a` or `b` let lessThanEqual =-        ./lessThanEqual.dhall sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99+        missing+          sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99       ? ./lessThanEqual.dhall  let max
dhall-lang/Prelude/Natural/min view
@@ -1,2 +1,3 @@-  ./min.dhall sha256:f25f9c462e4dbf0eb15f9ff6ac840c6e9c82255a7f4f2ab408bdab338e028710+  missing+    sha256:f25f9c462e4dbf0eb15f9ff6ac840c6e9c82255a7f4f2ab408bdab338e028710 ? ./min.dhall
dhall-lang/Prelude/Natural/min.dhall view
@@ -1,6 +1,7 @@ --| `min a b` returns the smaller of `a` or `b` let lessThanEqual =-        ./lessThanEqual.dhall sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99+        missing+          sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99       ? ./lessThanEqual.dhall  let min
dhall-lang/Prelude/Natural/odd view
@@ -1,2 +1,3 @@-  ./odd.dhall sha256:ab3c729262c642ec1cdb72a81e910fcfaf2aea13e3961d0bf1bec83efea5aac5+  missing+    sha256:ab3c729262c642ec1cdb72a81e910fcfaf2aea13e3961d0bf1bec83efea5aac5 ? ./odd.dhall
dhall-lang/Prelude/Natural/package.dhall view
@@ -1,67 +1,89 @@ { build =-      ./build.dhall sha256:e7e25e6c4f1d8e573606ed1bef725396ac2de5c68f7c5d329ffc5822085b984c+      missing+        sha256:e7e25e6c4f1d8e573606ed1bef725396ac2de5c68f7c5d329ffc5822085b984c     ? ./build.dhall , enumerate =-      ./enumerate.dhall sha256:0cf083980a752b21ce0df9fc2222a4c139f50909e2353576e26a191002aa1ce3+      missing+        sha256:0cf083980a752b21ce0df9fc2222a4c139f50909e2353576e26a191002aa1ce3     ? ./enumerate.dhall , even =-      ./even.dhall sha256:b85b8b56892dfef881e1c0e79eade0b949528f792aac0ea42432b315ede4ee66+      missing+        sha256:b85b8b56892dfef881e1c0e79eade0b949528f792aac0ea42432b315ede4ee66     ? ./even.dhall , fold =-      ./fold.dhall sha256:fd01c931e585a8f5fd049af7b076b862ea164f1813b34800c7616a49e549ee06+      missing+        sha256:fd01c931e585a8f5fd049af7b076b862ea164f1813b34800c7616a49e549ee06     ? ./fold.dhall , isZero =-      ./isZero.dhall sha256:1be98236800ed2d5cff44f16ca02b34b0c37dfa239d9e0d63d9d2c6eeae3d1d1+      missing+        sha256:1be98236800ed2d5cff44f16ca02b34b0c37dfa239d9e0d63d9d2c6eeae3d1d1     ? ./isZero.dhall , odd =-      ./odd.dhall sha256:ab3c729262c642ec1cdb72a81e910fcfaf2aea13e3961d0bf1bec83efea5aac5+      missing+        sha256:ab3c729262c642ec1cdb72a81e910fcfaf2aea13e3961d0bf1bec83efea5aac5     ? ./odd.dhall , product =-      ./product.dhall sha256:e3e6fd76207875b81d39f79fdbc90b5e640444c04fb3d84c2c9326748f0b26e6+      missing+        sha256:e3e6fd76207875b81d39f79fdbc90b5e640444c04fb3d84c2c9326748f0b26e6     ? ./product.dhall , sum =-      ./sum.dhall sha256:33f7f4c3aff62e5ecf4848f964363133452d420dcde045784518fb59fa970037+      missing+        sha256:33f7f4c3aff62e5ecf4848f964363133452d420dcde045784518fb59fa970037     ? ./sum.dhall , show =-      ./show.dhall sha256:684ed560ad86f438efdea229eca122c29e8e14f397ed32ec97148d578ca5aa21+      missing+        sha256:684ed560ad86f438efdea229eca122c29e8e14f397ed32ec97148d578ca5aa21     ? ./show.dhall , toDouble =-      ./toDouble.dhall sha256:d5eb52143dcd35b46a6f0cdb2d3cbf31a14b6daeba56e29066f8e344c9fb6e81+      missing+        sha256:d5eb52143dcd35b46a6f0cdb2d3cbf31a14b6daeba56e29066f8e344c9fb6e81     ? ./toDouble.dhall , toInteger =-      ./toInteger.dhall sha256:160d2d278619f3da34a1f4f02e739a447e4f2aa5a2978c45b710515b41491e1f+      missing+        sha256:160d2d278619f3da34a1f4f02e739a447e4f2aa5a2978c45b710515b41491e1f     ? ./toInteger.dhall , lessThan =-      ./lessThan.dhall sha256:3381b66749290769badf8855d8a3f4af62e8de52d1364d838a9d1e20c94fa70c+      missing+        sha256:3381b66749290769badf8855d8a3f4af62e8de52d1364d838a9d1e20c94fa70c     ? ./lessThan.dhall , lessThanEqual =-      ./lessThanEqual.dhall sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99+      missing+        sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99     ? ./lessThanEqual.dhall , equal =-      ./equal.dhall sha256:7f108edfa35ddc7cebafb24dc073478e93a802e13b5bc3fd22f4768c9b066e60+      missing+        sha256:7f108edfa35ddc7cebafb24dc073478e93a802e13b5bc3fd22f4768c9b066e60     ? ./equal.dhall , greaterThanEqual =-      ./greaterThanEqual.dhall sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4+      missing+        sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4     ? ./greaterThanEqual.dhall , greaterThan =-      ./greaterThan.dhall sha256:f702abcdfcd7ad73619b9285d7e41c3a1d017fb6b8d037cf40bd93bf30c09b2c+      missing+        sha256:f702abcdfcd7ad73619b9285d7e41c3a1d017fb6b8d037cf40bd93bf30c09b2c     ? ./greaterThan.dhall , min =-      ./min.dhall sha256:f25f9c462e4dbf0eb15f9ff6ac840c6e9c82255a7f4f2ab408bdab338e028710+      missing+        sha256:f25f9c462e4dbf0eb15f9ff6ac840c6e9c82255a7f4f2ab408bdab338e028710     ? ./min.dhall , max =-      ./max.dhall sha256:1f3b18da330223ab039fad11693da72c7e68d516f50502c73f41a89a097b62f7+      missing+        sha256:1f3b18da330223ab039fad11693da72c7e68d516f50502c73f41a89a097b62f7     ? ./max.dhall , listMin =-      ./listMin.dhall sha256:ee70b0d010bbca6012162e8ae1f6e9d9bd10a152675509b0f23145b98b5d43c6+      missing+        sha256:ee70b0d010bbca6012162e8ae1f6e9d9bd10a152675509b0f23145b98b5d43c6     ? ./listMin.dhall , listMax =-      ./listMax.dhall sha256:20906ffcc9970f740106d4516cb7868b43d75ff8c9f00ff8a9680ae68c48a472+      missing+        sha256:20906ffcc9970f740106d4516cb7868b43d75ff8c9f00ff8a9680ae68c48a472     ? ./listMax.dhall , sort =-      ./sort.dhall sha256:36ce8b3e5538454763987ca904d8d7c5ba34c2147434a19eddd51f684432b260+      missing+        sha256:36ce8b3e5538454763987ca904d8d7c5ba34c2147434a19eddd51f684432b260     ? ./sort.dhall , subtract =-      ./subtract.dhall sha256:b9277ac637d09142a3a3ac79137ef5955c42f8b33b6746d59db2c9d75ccdd745+      missing+        sha256:b9277ac637d09142a3a3ac79137ef5955c42f8b33b6746d59db2c9d75ccdd745     ? ./subtract.dhall }
dhall-lang/Prelude/Natural/product view
@@ -1,2 +1,3 @@-  ./product.dhall sha256:e3e6fd76207875b81d39f79fdbc90b5e640444c04fb3d84c2c9326748f0b26e6+  missing+    sha256:e3e6fd76207875b81d39f79fdbc90b5e640444c04fb3d84c2c9326748f0b26e6 ? ./product.dhall
dhall-lang/Prelude/Natural/show view
@@ -1,2 +1,3 @@-  ./show.dhall sha256:684ed560ad86f438efdea229eca122c29e8e14f397ed32ec97148d578ca5aa21+  missing+    sha256:684ed560ad86f438efdea229eca122c29e8e14f397ed32ec97148d578ca5aa21 ? ./show.dhall
dhall-lang/Prelude/Natural/sort view
@@ -1,2 +1,3 @@-  ./sort.dhall sha256:36ce8b3e5538454763987ca904d8d7c5ba34c2147434a19eddd51f684432b260+  missing+    sha256:36ce8b3e5538454763987ca904d8d7c5ba34c2147434a19eddd51f684432b260 ? ./sort.dhall
dhall-lang/Prelude/Natural/sort.dhall view
@@ -1,14 +1,17 @@ --| `sort` sorts a `List` of `Natural`s in ascending order let greaterThanEqual =-        ./greaterThanEqual.dhall sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4+        missing+          sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4       ? ./greaterThanEqual.dhall  let listMin =-        ./listMin.dhall sha256:ee70b0d010bbca6012162e8ae1f6e9d9bd10a152675509b0f23145b98b5d43c6+        missing+          sha256:ee70b0d010bbca6012162e8ae1f6e9d9bd10a152675509b0f23145b98b5d43c6       ? ./listMin.dhall  let List/partition =-        ../List/partition.dhall sha256:38147ac6d750a6492736dd90cc967bf09aa405c499de943c64fab7b86ae02f03+        missing+          sha256:38147ac6d750a6492736dd90cc967bf09aa405c499de943c64fab7b86ae02f03       ? ../List/partition.dhall  let Accumulator = { sorted : List Natural, rest : List Natural }
dhall-lang/Prelude/Natural/subtract view
@@ -1,2 +1,3 @@-  ./subtract.dhall sha256:b9277ac637d09142a3a3ac79137ef5955c42f8b33b6746d59db2c9d75ccdd745+  missing+    sha256:b9277ac637d09142a3a3ac79137ef5955c42f8b33b6746d59db2c9d75ccdd745 ? ./subtract.dhall
dhall-lang/Prelude/Natural/sum view
@@ -1,2 +1,3 @@-  ./sum.dhall sha256:33f7f4c3aff62e5ecf4848f964363133452d420dcde045784518fb59fa970037+  missing+    sha256:33f7f4c3aff62e5ecf4848f964363133452d420dcde045784518fb59fa970037 ? ./sum.dhall
dhall-lang/Prelude/Natural/toDouble view
@@ -1,2 +1,3 @@-  ./toDouble.dhall sha256:d5eb52143dcd35b46a6f0cdb2d3cbf31a14b6daeba56e29066f8e344c9fb6e81+  missing+    sha256:d5eb52143dcd35b46a6f0cdb2d3cbf31a14b6daeba56e29066f8e344c9fb6e81 ? ./toDouble.dhall
dhall-lang/Prelude/Natural/toInteger view
@@ -1,2 +1,3 @@-  ./toInteger.dhall sha256:160d2d278619f3da34a1f4f02e739a447e4f2aa5a2978c45b710515b41491e1f+  missing+    sha256:160d2d278619f3da34a1f4f02e739a447e4f2aa5a2978c45b710515b41491e1f ? ./toInteger.dhall
+ dhall-lang/Prelude/NonEmpty/Type.dhall view
@@ -0,0 +1,9 @@+{-|+A `NonEmpty` list has at least one element and supports many of the same+operations as `List`s+-}+let NonEmpty+    : Type → Type+    = λ(a : Type) → { head : a, tail : List a }++in  NonEmpty
+ dhall-lang/Prelude/NonEmpty/all.dhall view
@@ -0,0 +1,34 @@+{-|+Returns `True` if the supplied function returns `True` for all elements in the+`NonEmpty` list+-}+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ./Type.dhall++let NonEmpty/toList =+        missing+          sha256:0977fe14b77232a4451dcf409c43df4589c4b3cdde7b613aab8df183be1b53f5+      ? ./toList.dhall++let all+    : ∀(a : Type) → (a → Bool) → NonEmpty a → Bool+    = λ(a : Type) →+      λ(f : a → Bool) →+      λ(xs : NonEmpty a) →+        List/fold+          a+          (NonEmpty/toList a xs)+          Bool+          (λ(x : a) → λ(r : Bool) → f x && r)+          True++let example0 =+      assert : all Natural Natural/even { head = 2, tail = [ 3, 5 ] } ≡ False++let example1 =+        assert+      : all Natural Natural/even { head = 2, tail = [] : List Natural } ≡ True++in  all
+ dhall-lang/Prelude/NonEmpty/any.dhall view
@@ -0,0 +1,34 @@+{-|+Returns `True` if the supplied function returns `True` for any element in the+`NonEmpty` list+-}+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ./Type.dhall++let NonEmpty/toList =+        missing+          sha256:0977fe14b77232a4451dcf409c43df4589c4b3cdde7b613aab8df183be1b53f5+      ? ./toList.dhall++let any+    : ∀(a : Type) → (a → Bool) → NonEmpty a → Bool+    = λ(a : Type) →+      λ(f : a → Bool) →+      λ(xs : NonEmpty a) →+        List/fold+          a+          (NonEmpty/toList a xs)+          Bool+          (λ(x : a) → λ(r : Bool) → f x || r)+          False++let example0 =+      assert : any Natural Natural/even { head = 2, tail = [ 3, 5 ] } ≡ True++let example1 =+        assert+      : any Natural Natural/even { head = 3, tail = [] : List Natural } ≡ False++in  any
+ dhall-lang/Prelude/NonEmpty/concat.dhall view
@@ -0,0 +1,61 @@+{-|+Concatenate a `NonEmpty` list of `NonEmpty` lists into a single `NonEmpty`+list+-}+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ./Type.dhall++let NonEmpty/toList =+        missing+          sha256:0977fe14b77232a4451dcf409c43df4589c4b3cdde7b613aab8df183be1b53f5+      ? ./toList.dhall++let List/concatMap =+        missing+          sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64+      ? ../List/concatMap.dhall++let concat+    : ∀(a : Type) → NonEmpty (NonEmpty a) → NonEmpty a+    = λ(a : Type) →+      λ(xss : NonEmpty (NonEmpty a)) →+        { head = xss.head.head+        , tail =+              xss.head.tail+            # List/concatMap (NonEmpty a) a (NonEmpty/toList a) xss.tail+        }++let example0 =+        assert+      :   concat+            Natural+            { head = { head = 0, tail = [ 1, 2 ] }+            , tail =+              [ { head = 3, tail = [ 4 ] }, { head = 5, tail = [ 6, 7, 8 ] } ]+            }+        ≡ { head = 0, tail = [ 1, 2, 3, 4, 5, 6, 7, 8 ] }++let example1 =+        assert+      :   concat+            Natural+            { head = { head = 0, tail = [] : List Natural }+            , tail =+              [ { head = 1, tail = [] : List Natural }+              , { head = 2, tail = [] : List Natural }+              ]+            }+        ≡ { head = 0, tail = [ 1, 2 ] : List Natural }++let example2 =+        assert+      :   concat+            Natural+            { head = { head = 0, tail = [] : List Natural }+            , tail = [] : List (NonEmpty Natural)+            }+        ≡ { head = 0, tail = [] : List Natural }++in  concat
+ dhall-lang/Prelude/NonEmpty/concatMap.dhall view
@@ -0,0 +1,56 @@+{-|+Transform a `NonEmpty` list by applying a function to each element and+flattening the results+-}+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ./Type.dhall++let NonEmpty/toList =+        missing+          sha256:0977fe14b77232a4451dcf409c43df4589c4b3cdde7b613aab8df183be1b53f5+      ? ./toList.dhall++let List/concatMap =+        missing+          sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64+      ? ../List/concatMap.dhall++let concatMap+    : ∀(a : Type) → ∀(b : Type) → (a → NonEmpty b) → NonEmpty a → NonEmpty b+    = λ(a : Type) →+      λ(b : Type) →+      λ(f : a → NonEmpty b) →+      λ(xs : NonEmpty a) →+        let ys = f xs.head++        in  { head = ys.head+            , tail =+                  ys.tail+                # List/concatMap+                    a+                    b+                    (λ(x : a) → NonEmpty/toList b (f x))+                    xs.tail+            }++let example0 =+        assert+      :   concatMap+            Natural+            Natural+            (λ(n : Natural) → { head = n, tail = [ n ] })+            { head = 2, tail = [ 3, 5 ] }+        ≡ { head = 2, tail = [ 2, 3, 3, 5, 5 ] }++let example1 =+        assert+      :   concatMap+            Natural+            Natural+            (λ(n : Natural) → { head = n, tail = [ n ] })+            { head = 2, tail = [] : List Natural }+        ≡ { head = 2, tail = [ 2 ] }++in  concatMap
+ dhall-lang/Prelude/NonEmpty/head.dhall view
@@ -0,0 +1,13 @@+--| Retrieve the first element of the `NonEmpty` list+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ./Type.dhall++let head+    : ∀(a : Type) → NonEmpty a → a+    = λ(a : Type) → λ(xs : NonEmpty a) → xs.head++let example = assert : head Natural { head = 0, tail = [ 1, 2 ] } ≡ 0++in  head
+ dhall-lang/Prelude/NonEmpty/index.dhall view
@@ -0,0 +1,33 @@+--| Retrieve an element from a `NonEmpty` list using its 0-based index+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ./Type.dhall++let List/index =+        missing+          sha256:e657b55ecae4d899465c3032cb1a64c6aa6dc2aa3034204f3c15ce5c96c03e63+      ? ../List/index.dhall++let index+    : Natural → ∀(a : Type) → NonEmpty a → Optional a+    = λ(n : Natural) →+      λ(a : Type) →+      λ(xs : NonEmpty a) →+        if    Natural/isZero n+        then  Some xs.head+        else  List/index (Natural/subtract 1 n) a xs.tail++let property =+      λ(n : Natural) →+      λ(a : Type) →+      λ(xs : NonEmpty a) →+        assert : index 0 a xs ≡ Some xs.head++let example0 = assert : index 1 Natural { head = 2, tail = [ 3, 5 ] } ≡ Some 3++let example1 =+        assert+      : index 1 Natural { head = 2, tail = [] : List Natural } ≡ None Natural++in  index
+ dhall-lang/Prelude/NonEmpty/indexed.dhall view
@@ -0,0 +1,41 @@+--| Tag each element of the `NonEmpty` list with its index+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ./Type.dhall++let List/map =+        missing+          sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680+      ? ../List/map.dhall++let indexed+    : ∀(a : Type) → NonEmpty a → NonEmpty { index : Natural, value : a }+    = λ(a : Type) →+      λ(xs : NonEmpty a) →+        { head = { index = 0, value = xs.head }+        , tail =+            List/map+              { index : Natural, value : a }+              { index : Natural, value : a }+              ( λ(ix : { index : Natural, value : a }) →+                  { index = ix.index + 1, value = ix.value }+              )+              (List/indexed a xs.tail)+        }++let example0 =+        assert+      :   indexed Bool { head = True, tail = [ False, True ] }+        ≡ { head = { index = 0, value = True }+          , tail = [ { index = 1, value = False }, { index = 2, value = True } ]+          }++let example1 =+        assert+      :   indexed Bool { head = True, tail = [] : List Bool }+        ≡ { head = { index = 0, value = True }+          , tail = [] : List { index : Natural, value : Bool }+          }++in  indexed
+ dhall-lang/Prelude/NonEmpty/last.dhall view
@@ -0,0 +1,17 @@+--| Retrieve the last element of the `NonEmpty` list+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ./Type.dhall++let last+    : ∀(a : Type) → NonEmpty a → a+    = λ(a : Type) →+      λ(xs : NonEmpty a) →+        merge { Some = λ(x : a) → x, None = xs.head } (List/last a xs.tail)++let example0 = assert : last Natural { head = 0, tail = [ 1, 2 ] } ≡ 2++let example1 = assert : last Natural { head = 0, tail = [] : List Natural } ≡ 0++in  last
+ dhall-lang/Prelude/NonEmpty/length.dhall view
@@ -0,0 +1,16 @@+--| Returns the number of elements in a `NonEmpty` list+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ./Type.dhall++let length+    : ∀(a : Type) → NonEmpty a → Natural+    = λ(a : Type) → λ(xs : NonEmpty a) → List/length a xs.tail + 1++let example0 = assert : length Natural { head = 0, tail = [ 1, 2 ] } ≡ 3++let example1 =+      assert : length Natural { head = 0, tail = [] : List Natural } ≡ 1++in  length
+ dhall-lang/Prelude/NonEmpty/make.dhall view
@@ -0,0 +1,18 @@+{-|+Create a `NonEmpty` list using a function instead of a record++This might come in handy if you want to decouple the `NonEmpty` list+construction from the specific names of the fields.+-}+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ./Type.dhall++let make+    : ∀(a : Type) → ∀(head : a) → ∀(tail : List a) → NonEmpty a+    = λ(a : Type) → λ(head : a) → λ(tail : List a) → { head, tail }++let example = assert : make Natural 1 [ 2, 3 ] ≡ { head = 1, tail = [ 2, 3 ] }++in  make
+ dhall-lang/Prelude/NonEmpty/map.dhall view
@@ -0,0 +1,30 @@+--| Transform a `NonEmpty` list by applying a function to each element+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ./Type.dhall++let List/map =+        missing+          sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680+      ? ../List/map.dhall++let map+    : ∀(a : Type) → ∀(b : Type) → (a → b) → NonEmpty a → NonEmpty b+    = λ(a : Type) →+      λ(b : Type) →+      λ(f : a → b) →+      λ(xs : NonEmpty a) →+        { head = f xs.head, tail = List/map a b f xs.tail }++let example0 =+        assert+      :   map Natural Bool Natural/even { head = 2, tail = [ 3, 5 ] }+        ≡ { head = True, tail = [ False, False ] }++let example1 =+        assert+      :   map Natural Bool Natural/even { head = 2, tail = [] : List Natural }+        ≡ { head = True, tail = [] : List Bool }++in  map
+ dhall-lang/Prelude/NonEmpty/package.dhall view
@@ -0,0 +1,73 @@+{ Type =+      missing+        sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+    ? ./Type.dhall+, all =+      missing+        sha256:f2f9389d94f4deb5b918b2e50c1093b57e00b37ddd3ab2b43959993b1cb519b6+    ? ./all.dhall+, any =+      missing+        sha256:7662b665840e41b12a28190eec3aaab9201fcb90c00a8ec3666d549e1020992f+    ? ./any.dhall+, concat =+      missing+        sha256:6d55181938c06c6b806877028f6a241912e9c0935d9a10dd958775bf21e0f64d+    ? ./concat.dhall+, concatMap =+      missing+        sha256:fc33fa9449dc8f74dd8c8be379b7b7c4b0433e2b65650370d81d9a7111a590e2+    ? ./concatMap.dhall+, head =+      missing+        sha256:6b9551c97b89fe666d2e03392a4af5e87abfdbdb0aa0e29fc4b3aa1b318474e7+    ? ./head.dhall+, index =+      missing+        sha256:0ba2fcc9227fab10676cd61b47a18d779818a19c16727c7cc4b4c78e114fd663+    ? ./index.dhall+, indexed =+      missing+        sha256:9dae2c1fecd142df837e98769b5bbdd0bfe25c35a93af1064b4e62f9c780ae6b+    ? ./indexed.dhall+, last =+      missing+        sha256:f83115492b6e408d0b662a68440620f7f3df07b56e7ed66dab77a6e65b121250+    ? ./last.dhall+, length =+      missing+        sha256:eef3b857a164487cfdb960e3298c4731970b7a430011289cba35a9ad722ac989+    ? ./length.dhall+, make =+      missing+        sha256:549de393673c4773c80a50ea578ea50d7f2c4c2eda31956e73fabc4e486f3b1e+    ? ./make.dhall+, map =+      missing+        sha256:93d53afe874bb2eed946c21ca5ada3c9716b7d00e6d8edfaba6484cd9c5a00bd+    ? ./map.dhall+, reverse =+      missing+        sha256:a6d810cdd3badffd4e7ca82091609a855cffac900c82d7ff3724463fbc2d5ff2+    ? ./reverse.dhall+, shifted =+      missing+        sha256:36156973d6916aed10cfd8c59be7c019516bf0a2c47b499a17a8ef0611e1c189+    ? ./shifted.dhall+, singleton =+      missing+        sha256:c9197aabe97695f7ca66f7419bf172d806b2c915594a8fc0d2ff6495db496ff2+    ? ./singleton.dhall+, toList =+      missing+        sha256:0977fe14b77232a4451dcf409c43df4589c4b3cdde7b613aab8df183be1b53f5+    ? ./toList.dhall+, unzip =+      missing+        sha256:d0b925bea32a29aad5cb48a84e8ef8cff750308afe1dd20b24eca19e4e999abc+    ? ./unzip.dhall+, zip =+      missing+        sha256:073f8b4808b6d1db84964f772f6291e6ea193602163438db43fa282c560c01e4+    ? ./zip.dhall+}
+ dhall-lang/Prelude/NonEmpty/reverse.dhall view
@@ -0,0 +1,35 @@+--| Reverse a `NonEmpty` list+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ./Type.dhall++let List/drop =+        missing+          sha256:af983ba3ead494dd72beed05c0f3a17c36a4244adedf7ced502c6512196ed0cf+      ? ../List/drop.dhall++let reverse+    : ∀(a : Type) → NonEmpty a → NonEmpty a+    = λ(a : Type) →+      λ(xs : NonEmpty a) →+        let ys = List/reverse a xs.tail++        in  merge+              { Some =+                  λ(y : a) → { head = y, tail = List/drop 1 a ys # [ xs.head ] }+              , None = { head = xs.head, tail = [] : List a }+              }+              (List/head a ys)++let example =+        assert+      :   reverse Natural { head = 0, tail = [ 1, 2 ] }+        ≡ { head = 2, tail = [ 1, 0 ] }++let example1 =+        assert+      :   reverse Natural { head = 0, tail = [] : List Natural }+        ≡ { head = 0, tail = [] : List Natural }++in  reverse
+ dhall-lang/Prelude/NonEmpty/shifted.dhall view
@@ -0,0 +1,101 @@+{-|+Combine a `NonEmpty` list of `NonEmpty` lists, offsetting the `index` of each+element by the number of elements in preceding lists+-}+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ./Type.dhall++let NonEmpty/toList =+        missing+          sha256:0977fe14b77232a4451dcf409c43df4589c4b3cdde7b613aab8df183be1b53f5+      ? ./toList.dhall++let List/map =+        missing+          sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680+      ? ../List/map.dhall++let List/shifted =+        missing+          sha256:54fb22c7e952ebce1cfc0fcdd33ce4cfa817bff9d6564af268dea6685f8b5dfe+      ? ../List/shifted.dhall++let shifted+    : ∀(a : Type) →+      NonEmpty (NonEmpty { index : Natural, value : a }) →+        NonEmpty { index : Natural, value : a }+    = λ(a : Type) →+      λ(kvss : NonEmpty (NonEmpty { index : Natural, value : a })) →+        { head = kvss.head.head+        , tail =+            List/shifted+              a+              (   [ kvss.head.tail ]+                # List/map+                    (NonEmpty { index : Natural, value : a })+                    (List { index : Natural, value : a })+                    ( λ(kvs : NonEmpty { index : Natural, value : a }) →+                        List/map+                          { index : Natural, value : a }+                          { index : Natural, value : a }+                          ( λ(kv : { index : Natural, value : a }) →+                              { index = kv.index + 1, value = kv.value }+                          )+                          (NonEmpty/toList { index : Natural, value : a } kvs)+                    )+                    kvss.tail+              )+        }++let example0 =+        assert+      :   shifted+            Bool+            { head =+              { head = { index = 0, value = True }+              , tail =+                [ { index = 1, value = True }, { index = 2, value = True } ]+              }+            , tail =+              [ { head = { index = 0, value = False }+                , tail = [ { index = 1, value = False } ]+                }+              , { head = { index = 0, value = True }+                , tail =+                  [ { index = 1, value = True }+                  , { index = 2, value = True }+                  , { index = 3, value = True }+                  ]+                }+              ]+            }+        ≡ { head = { index = 0, value = True }+          , tail =+            [ { index = 1, value = True }+            , { index = 2, value = True }+            , { index = 3, value = False }+            , { index = 4, value = False }+            , { index = 5, value = True }+            , { index = 6, value = True }+            , { index = 7, value = True }+            , { index = 8, value = True }+            ]+          }++let example1 =+        assert+      :   shifted+            Bool+            { head =+              { head = { index = 0, value = True }+              , tail = [] : List { index : Natural, value : Bool }+              }+            , tail = [] : List (NonEmpty { index : Natural, value : Bool })+            }+        ≡ { head = { index = 0, value = True }+          , tail = [] : List { index : Natural, value : Bool }+          }++in  shifted
+ dhall-lang/Prelude/NonEmpty/singleton.dhall view
@@ -0,0 +1,14 @@+--| Create a `NonEmpty` list with just one element+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ./Type.dhall++let singleton+    : ∀(a : Type) → a → NonEmpty a+    = λ(a : Type) → λ(x : a) → { head = x, tail = [] : List a }++let example =+      assert : singleton Natural 2 ≡ { head = 2, tail = [] : List Natural }++in  singleton
+ dhall-lang/Prelude/NonEmpty/toList.dhall view
@@ -0,0 +1,17 @@+--| Convert a `NonEmpty` list into the equivalent `List`+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ./Type.dhall++let toList+    : ∀(a : Type) → NonEmpty a → List a+    = λ(a : Type) → λ(xs : NonEmpty a) → [ xs.head ] # xs.tail++let example0 =+      assert : toList Natural { head = 2, tail = [ 3, 5 ] } ≡ [ 2, 3, 5 ]++let example1 =+      assert : toList Natural { head = 2, tail = [] : List Natural } ≡ [ 2 ]++in  toList
+ dhall-lang/Prelude/NonEmpty/unzip.dhall view
@@ -0,0 +1,58 @@+--| Unzip a `NonEmpty` list into two separate `NonEmpty` lists+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ./Type.dhall++let NonEmpty/map =+        missing+          sha256:93d53afe874bb2eed946c21ca5ada3c9716b7d00e6d8edfaba6484cd9c5a00bd+      ? ./map.dhall++let unzip+    : ∀(a : Type) →+      ∀(b : Type) →+      NonEmpty { _1 : a, _2 : b } →+        { _1 : NonEmpty a, _2 : NonEmpty b }+    = λ(a : Type) →+      λ(b : Type) →+      λ(xs : NonEmpty { _1 : a, _2 : b }) →+        { _1 =+            NonEmpty/map+              { _1 : a, _2 : b }+              a+              (λ(x : { _1 : a, _2 : b }) → x._1)+              xs+        , _2 =+            NonEmpty/map+              { _1 : a, _2 : b }+              b+              (λ(x : { _1 : a, _2 : b }) → x._2)+              xs+        }++let example0 =+        assert+      :   unzip+            Text+            Bool+            { head = { _1 = "ABC", _2 = True }+            , tail = [ { _1 = "DEF", _2 = False }, { _1 = "GHI", _2 = True } ]+            }+        ≡ { _1 = { head = "ABC", tail = [ "DEF", "GHI" ] }+          , _2 = { head = True, tail = [ False, True ] }+          }++let example1 =+        assert+      :   unzip+            Text+            Bool+            { head = { _1 = "ABC", _2 = True }+            , tail = [] : List { _1 : Text, _2 : Bool }+            }+        ≡ { _1 = { head = "ABC", tail = [] : List Text }+          , _2 = { head = True, tail = [] : List Bool }+          }++in  unzip
+ dhall-lang/Prelude/NonEmpty/zip.dhall view
@@ -0,0 +1,63 @@+{-|+Zip two `NonEmpty` lists into a single `NonEmpty`++The resulting `NonEmpty` will have the length of the shortest of its arguments.+-}+let NonEmpty =+        missing+          sha256:e2e247455a858317e470e0e4affca8ac07f9f130570ece9cb7ac1f4ea3deb87f+      ? ./Type.dhall++let List/zip =+        missing+          sha256:85ed955eabf3998767f4ad2a28e57d40cd4c68a95519d79e9b622f1d26d979da+      ? ../List/zip.dhall++let zip+    : ∀(a : Type) →+      NonEmpty a →+      ∀(b : Type) →+      NonEmpty b →+        NonEmpty { _1 : a, _2 : b }+    = λ(a : Type) →+      λ(xs : NonEmpty a) →+      λ(b : Type) →+      λ(ys : NonEmpty b) →+        { head = { _1 = xs.head, _2 = ys.head }+        , tail = List/zip a xs.tail b ys.tail+        }++let example0 =+        assert+      :   zip+            Text+            { head = "ABC", tail = [ "DEF", "GHI" ] }+            Natural+            { head = 1, tail = [ 2, 3 ] }+        ≡ { head = { _1 = "ABC", _2 = 1 }+          , tail = [ { _1 = "DEF", _2 = 2 }, { _1 = "GHI", _2 = 3 } ]+          }++let example1 =+        assert+      :   zip+            Text+            { head = "ABC", tail = [ "DEF" ] }+            Bool+            { head = True, tail = [] : List Bool }+        ≡ { head = { _1 = "ABC", _2 = True }+          , tail = [] : List { _1 : Text, _2 : Bool }+          }++let example2 =+        assert+      :   zip+            Text+            { head = "ABC", tail = [] : List Text }+            Natural+            { head = 1, tail = [ 2 ] }+        ≡ { head = { _1 = "ABC", _2 = 1 }+          , tail = [] : List { _1 : Text, _2 : Natural }+          }++in  zip
+ dhall-lang/Prelude/Operator/package.dhall view
@@ -0,0 +1,85 @@+{-+Note: This package does not use one file per function because the operator+names contain symbols such as `*` that may cause problems.+-}+let {-+        `+` m n++    computes `m + n`+    -} `+`+    : Natural → Natural → Natural+    = λ(m : Natural) → λ(n : Natural) → m + n++let example1 = assert : `+` 2 1 ≡ 3++let {-+        `*` m n++    computes `m * n`+    -} `*`+    : Natural → Natural → Natural+    = λ(m : Natural) → λ(n : Natural) → m * n++let example2 = assert : `*` 21 2 ≡ 42++let {-+        `++` m n++    computes `m ++ n`+    -} `++`+    : Text → Text → Text+    = λ(m : Text) → λ(n : Text) → m ++ n++let example3 = assert : `++` "Hello" "Dhall" ≡ "HelloDhall"++let {-+        `#` Type m n++    computes `m # n`+    -} `#`+    : ∀(type : Type) → List type → List type → List type+    = λ(type : Type) → λ(m : List type) → λ(n : List type) → m # n++let example4 = assert : `#` Natural [ 1, 2 ] [ 3 ] ≡ [ 1, 2, 3 ]++let {-+        `==` m n++    computes `m == n`+    -} `==`+    : Bool → Bool → Bool+    = λ(m : Bool) → λ(n : Bool) → m == n++let example5 = assert : `==` True False ≡ False++let {-+        `!=` m n++    computes `m != n`+    -} `!=`+    : Bool → Bool → Bool+    = λ(m : Bool) → λ(n : Bool) → m != n++let example6 = assert : `!=` True False ≡ True++let {-+        `&&` m n++    computes `m && n`+    -} `&&`+    : Bool → Bool → Bool+    = λ(m : Bool) → λ(n : Bool) → m && n++let example7 = assert : `&&` False True ≡ False++let {-+        `||` m n++    computes `m || n`+    -} `||`+    : Bool → Bool → Bool+    = λ(m : Bool) → λ(n : Bool) → m || n++let example8 = assert : `||` False True ≡ True++in  { `+`, `*`, `++`, `#`, `==`, `!=`, `&&`, `||` }
dhall-lang/Prelude/Optional/all view
@@ -1,2 +1,3 @@-  ./all.dhall sha256:a303004b6def0a2a05bf5f0a8d54e84dd45d8bef581789186ac04924956a1695+  missing+    sha256:a303004b6def0a2a05bf5f0a8d54e84dd45d8bef581789186ac04924956a1695 ? ./all.dhall
dhall-lang/Prelude/Optional/any view
@@ -1,2 +1,3 @@-  ./any.dhall sha256:96a5cf4f31b3c598b09161dd3082f0a09f4328a4cefda6a7e09894b37b17b435+  missing+    sha256:96a5cf4f31b3c598b09161dd3082f0a09f4328a4cefda6a7e09894b37b17b435 ? ./any.dhall
dhall-lang/Prelude/Optional/build view
@@ -1,2 +1,3 @@-  ./build.dhall sha256:28e61294bf2dd59dc57cf74f719d1568e60b5ba46c28eac586bc937eff4a2af1+  missing+    sha256:28e61294bf2dd59dc57cf74f719d1568e60b5ba46c28eac586bc937eff4a2af1 ? ./build.dhall
dhall-lang/Prelude/Optional/concat view
@@ -1,2 +1,3 @@-  ./concat.dhall sha256:b7736bd3ebeab14c3912dfb534d0c970a025b001d06c2d5461d4b0e289e3cb7a+  missing+    sha256:b7736bd3ebeab14c3912dfb534d0c970a025b001d06c2d5461d4b0e289e3cb7a ? ./concat.dhall
+ dhall-lang/Prelude/Optional/concatMap.dhall view
@@ -0,0 +1,23 @@+--| Transform the value with a function and flatten the resulting `Optional`+let concatMap+    : ∀(a : Type) → ∀(b : Type) → (a → Optional b) → Optional a → Optional b+    = λ(a : Type) →+      λ(b : Type) →+      λ(f : a → Optional b) →+      λ(o : Optional a) →+        merge { Some = f, None = None b } o++let exampleFun+    : Natural → Optional Natural+    = λ(n : Natural) → if Natural/even n then Some (n + 1) else None Natural++let example0 =+      assert : concatMap Natural Natural exampleFun (Some 1) ≡ None Natural++let example1 = assert : concatMap Natural Natural exampleFun (Some 2) ≡ Some 3++let example2 =+        assert+      : concatMap Natural Natural exampleFun (None Natural) ≡ None Natural++in  concatMap
dhall-lang/Prelude/Optional/default view
@@ -1,2 +1,3 @@-  ./default.dhall sha256:5bd665b0d6605c374b3c4a7e2e2bd3b9c1e39323d41441149ed5e30d86e889ad+  missing+    sha256:5bd665b0d6605c374b3c4a7e2e2bd3b9c1e39323d41441149ed5e30d86e889ad ? ./default.dhall
+ dhall-lang/Prelude/Optional/equal.dhall view
@@ -0,0 +1,24 @@+let Optional/fold =+        missing+          sha256:c5b9d72f6f62bdaa0e196ac1c742cc175cd67a717b880fb8aec1333a5a4132cf+      ? ./fold.dhall++let Optional/null =+        missing+          sha256:3871180b87ecaba8b53fffb2a8b52d3fce98098fab09a6f759358b9e8042eedc+      ? ./null.dhall++let equal+    : forall (a : Type) -> (a -> a -> Bool) -> Optional a -> Optional a -> Bool+    = \(a : Type) ->+      \(compare : a -> a -> Bool) ->+      \(ox : Optional a) ->+      \(oy : Optional a) ->+        Optional/fold+          a+          ox+          Bool+          (\(x : a) -> Optional/fold a oy Bool (compare x) False)+          (Optional/null a oy)++in  equal
dhall-lang/Prelude/Optional/filter view
@@ -1,2 +1,3 @@-  ./filter.dhall sha256:54f0a487d578801819613fe000050c038c632edf1f9ccc57677e98ae0ef56b83+  missing+    sha256:54f0a487d578801819613fe000050c038c632edf1f9ccc57677e98ae0ef56b83 ? ./filter.dhall
dhall-lang/Prelude/Optional/fold view
@@ -1,2 +1,3 @@-  ./fold.dhall sha256:c5b9d72f6f62bdaa0e196ac1c742cc175cd67a717b880fb8aec1333a5a4132cf+  missing+    sha256:c5b9d72f6f62bdaa0e196ac1c742cc175cd67a717b880fb8aec1333a5a4132cf ? ./fold.dhall
dhall-lang/Prelude/Optional/fold.dhall view
@@ -13,9 +13,8 @@       λ(none : optional) →         merge { Some = some, None = none } o -let example0 = assert : fold Natural (Some 2) Natural (λ(x : Natural) → x) 0 ≡ 2+let example0 = assert : fold Natural (Some 2) Text Natural/show "0" ≡ "2" -let example1 =-      assert : fold Natural (None Natural) Natural (λ(x : Natural) → x) 0 ≡ 0+let example1 = assert : fold Natural (None Natural) Text Natural/show "0" ≡ "0"  in  fold
dhall-lang/Prelude/Optional/head view
@@ -1,2 +1,3 @@-  ./head.dhall sha256:4f256c9338b60a1933f41f2a8fafd861930a1e41770a644cdbac0622676fa34c+  missing+    sha256:4f256c9338b60a1933f41f2a8fafd861930a1e41770a644cdbac0622676fa34c ? ./head.dhall
dhall-lang/Prelude/Optional/last view
@@ -1,2 +1,3 @@-  ./last.dhall sha256:50400771ae19e9b75efa6581feec318ae1ade0b6a60e215df428c66c4b052707+  missing+    sha256:50400771ae19e9b75efa6581feec318ae1ade0b6a60e215df428c66c4b052707 ? ./last.dhall
dhall-lang/Prelude/Optional/length view
@@ -1,2 +1,3 @@-  ./length.dhall sha256:f168337c5244ded68c05ecf32ce068b6b87158881d07e87b8cb6853fc6982a85+  missing+    sha256:f168337c5244ded68c05ecf32ce068b6b87158881d07e87b8cb6853fc6982a85 ? ./length.dhall
dhall-lang/Prelude/Optional/map view
@@ -1,2 +1,3 @@-  ./map.dhall sha256:501534192d988218d43261c299cc1d1e0b13d25df388937add784778ab0054fa+  missing+    sha256:501534192d988218d43261c299cc1d1e0b13d25df388937add784778ab0054fa ? ./map.dhall
dhall-lang/Prelude/Optional/null view
@@ -1,2 +1,3 @@-  ./null.dhall sha256:3871180b87ecaba8b53fffb2a8b52d3fce98098fab09a6f759358b9e8042eedc+  missing+    sha256:3871180b87ecaba8b53fffb2a8b52d3fce98098fab09a6f759358b9e8042eedc ? ./null.dhall
dhall-lang/Prelude/Optional/package.dhall view
@@ -1,43 +1,65 @@ { all =-      ./all.dhall sha256:a303004b6def0a2a05bf5f0a8d54e84dd45d8bef581789186ac04924956a1695+      missing+        sha256:a303004b6def0a2a05bf5f0a8d54e84dd45d8bef581789186ac04924956a1695     ? ./all.dhall , any =-      ./any.dhall sha256:96a5cf4f31b3c598b09161dd3082f0a09f4328a4cefda6a7e09894b37b17b435+      missing+        sha256:96a5cf4f31b3c598b09161dd3082f0a09f4328a4cefda6a7e09894b37b17b435     ? ./any.dhall , build =-      ./build.dhall sha256:28e61294bf2dd59dc57cf74f719d1568e60b5ba46c28eac586bc937eff4a2af1+      missing+        sha256:28e61294bf2dd59dc57cf74f719d1568e60b5ba46c28eac586bc937eff4a2af1     ? ./build.dhall , concat =-      ./concat.dhall sha256:b7736bd3ebeab14c3912dfb534d0c970a025b001d06c2d5461d4b0e289e3cb7a+      missing+        sha256:b7736bd3ebeab14c3912dfb534d0c970a025b001d06c2d5461d4b0e289e3cb7a     ? ./concat.dhall+, concatMap =+      missing+        sha256:c06ae93e900a99299c9b4ec4912ca5395a0103ea88292205b08dd7e345632818+    ? ./concatMap.dhall , default =-      ./default.dhall sha256:5bd665b0d6605c374b3c4a7e2e2bd3b9c1e39323d41441149ed5e30d86e889ad+      missing+        sha256:5bd665b0d6605c374b3c4a7e2e2bd3b9c1e39323d41441149ed5e30d86e889ad     ? ./default.dhall+, equal =+      missing+        sha256:5411888399fe9c6720f7f3b59caf5eff3e8e8c30402d09f34e46a4457649a35a+    ? ./equal.dhall , filter =-      ./filter.dhall sha256:54f0a487d578801819613fe000050c038c632edf1f9ccc57677e98ae0ef56b83+      missing+        sha256:54f0a487d578801819613fe000050c038c632edf1f9ccc57677e98ae0ef56b83     ? ./filter.dhall , fold =-      ./fold.dhall sha256:c5b9d72f6f62bdaa0e196ac1c742cc175cd67a717b880fb8aec1333a5a4132cf+      missing+        sha256:c5b9d72f6f62bdaa0e196ac1c742cc175cd67a717b880fb8aec1333a5a4132cf     ? ./fold.dhall , head =-      ./head.dhall sha256:4f256c9338b60a1933f41f2a8fafd861930a1e41770a644cdbac0622676fa34c+      missing+        sha256:4f256c9338b60a1933f41f2a8fafd861930a1e41770a644cdbac0622676fa34c     ? ./head.dhall , last =-      ./last.dhall sha256:50400771ae19e9b75efa6581feec318ae1ade0b6a60e215df428c66c4b052707+      missing+        sha256:50400771ae19e9b75efa6581feec318ae1ade0b6a60e215df428c66c4b052707     ? ./last.dhall , length =-      ./length.dhall sha256:f168337c5244ded68c05ecf32ce068b6b87158881d07e87b8cb6853fc6982a85+      missing+        sha256:f168337c5244ded68c05ecf32ce068b6b87158881d07e87b8cb6853fc6982a85     ? ./length.dhall , map =-      ./map.dhall sha256:501534192d988218d43261c299cc1d1e0b13d25df388937add784778ab0054fa+      missing+        sha256:501534192d988218d43261c299cc1d1e0b13d25df388937add784778ab0054fa     ? ./map.dhall , null =-      ./null.dhall sha256:3871180b87ecaba8b53fffb2a8b52d3fce98098fab09a6f759358b9e8042eedc+      missing+        sha256:3871180b87ecaba8b53fffb2a8b52d3fce98098fab09a6f759358b9e8042eedc     ? ./null.dhall , toList =-      ./toList.dhall sha256:d78f160c619119ef12389e48a629ce293d69f7624c8d016b7a4767ab400344c4+      missing+        sha256:d78f160c619119ef12389e48a629ce293d69f7624c8d016b7a4767ab400344c4     ? ./toList.dhall , unzip =-      ./unzip.dhall sha256:d016c01ba91657a2f35609aa29087963d0f506bab0f41d5e8b7cd289dff39708+      missing+        sha256:d016c01ba91657a2f35609aa29087963d0f506bab0f41d5e8b7cd289dff39708     ? ./unzip.dhall }
dhall-lang/Prelude/Optional/toList view
@@ -1,2 +1,3 @@-  ./toList.dhall sha256:d78f160c619119ef12389e48a629ce293d69f7624c8d016b7a4767ab400344c4+  missing+    sha256:d78f160c619119ef12389e48a629ce293d69f7624c8d016b7a4767ab400344c4 ? ./toList.dhall
dhall-lang/Prelude/Optional/unzip view
@@ -1,2 +1,3 @@-  ./unzip.dhall sha256:d016c01ba91657a2f35609aa29087963d0f506bab0f41d5e8b7cd289dff39708+  missing+    sha256:d016c01ba91657a2f35609aa29087963d0f506bab0f41d5e8b7cd289dff39708 ? ./unzip.dhall
dhall-lang/Prelude/Text/concat view
@@ -1,2 +1,3 @@-  ./concat.dhall sha256:731265b0288e8a905ecff95c97333ee2db614c39d69f1514cb8eed9259745fc0+  missing+    sha256:731265b0288e8a905ecff95c97333ee2db614c39d69f1514cb8eed9259745fc0 ? ./concat.dhall
dhall-lang/Prelude/Text/concatMap view
@@ -1,2 +1,3 @@-  ./concatMap.dhall sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f+  missing+    sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f ? ./concatMap.dhall
dhall-lang/Prelude/Text/concatMapSep view
@@ -1,2 +1,3 @@-  ./concatMapSep.dhall sha256:c272aca80a607bc5963d1fcb38819e7e0d3e72ac4d02b1183b1afb6a91340840+  missing+    sha256:c272aca80a607bc5963d1fcb38819e7e0d3e72ac4d02b1183b1afb6a91340840 ? ./concatMapSep.dhall
dhall-lang/Prelude/Text/concatSep view
@@ -1,2 +1,3 @@-  ./concatSep.dhall sha256:e4401d69918c61b92a4c0288f7d60a6560ca99726138ed8ebc58dca2cd205e58+  missing+    sha256:e4401d69918c61b92a4c0288f7d60a6560ca99726138ed8ebc58dca2cd205e58 ? ./concatSep.dhall
dhall-lang/Prelude/Text/default view
@@ -1,2 +1,3 @@-  ./default.dhall sha256:f532c8891b1e427d90a6cc07cf7e793a4c84b0765e1bfe69f186ee2ec91c1edf+  missing+    sha256:f532c8891b1e427d90a6cc07cf7e793a4c84b0765e1bfe69f186ee2ec91c1edf ? ./default.dhall
dhall-lang/Prelude/Text/defaultMap view
@@ -1,2 +1,3 @@-  ./defaultMap.dhall sha256:3a3fa1264f6198800c27483cb144de2c5366484876d60b9c739a710ce0288588+  missing+    sha256:3a3fa1264f6198800c27483cb144de2c5366484876d60b9c739a710ce0288588 ? ./defaultMap.dhall
+ dhall-lang/Prelude/Text/lowerASCII.dhall view
@@ -0,0 +1,56 @@+{-|+Lowercase all ASCII characters++Note that this will also lowercase decomposed Unicode characters that contain+codepoints in the ASCII range+-}+let lowerASCII+    : Text → Text+    = List/fold+        (Text → Text)+        [ Text/replace "A" "a"+        , Text/replace "B" "b"+        , Text/replace "C" "c"+        , Text/replace "D" "d"+        , Text/replace "E" "e"+        , Text/replace "F" "f"+        , Text/replace "G" "g"+        , Text/replace "H" "h"+        , Text/replace "I" "i"+        , Text/replace "J" "j"+        , Text/replace "K" "k"+        , Text/replace "L" "l"+        , Text/replace "M" "m"+        , Text/replace "N" "n"+        , Text/replace "O" "o"+        , Text/replace "P" "p"+        , Text/replace "Q" "q"+        , Text/replace "R" "r"+        , Text/replace "S" "s"+        , Text/replace "T" "t"+        , Text/replace "U" "u"+        , Text/replace "V" "v"+        , Text/replace "W" "w"+        , Text/replace "X" "x"+        , Text/replace "Y" "y"+        , Text/replace "Z" "z"+        ]+        Text+        (λ(replacement : Text → Text) → replacement)++let example0 = assert : lowerASCII "ABCdef" ≡ "abcdef"++let -- This does not lowercase precomposed Unicode characters+    --+    -- • The `Á` in the following example is U+00C1+    example1 =+      assert : lowerASCII "Á" ≡ "Á"++let -- … but this does lowercase decomposed Unicode characters+    --+    -- • The `Á` in the following example is U+0041 U+0301+    -- • The `á` in the following example is U+0061 U+0301+    example1 =+      assert : lowerASCII "Á" ≡ "á"++in  lowerASCII
dhall-lang/Prelude/Text/package.dhall view
@@ -1,28 +1,53 @@ { concat =-      ./concat.dhall sha256:731265b0288e8a905ecff95c97333ee2db614c39d69f1514cb8eed9259745fc0+      missing+        sha256:731265b0288e8a905ecff95c97333ee2db614c39d69f1514cb8eed9259745fc0     ? ./concat.dhall , concatMap =-      ./concatMap.dhall sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f+      missing+        sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f     ? ./concatMap.dhall , concatMapSep =-      ./concatMapSep.dhall sha256:c272aca80a607bc5963d1fcb38819e7e0d3e72ac4d02b1183b1afb6a91340840+      missing+        sha256:c272aca80a607bc5963d1fcb38819e7e0d3e72ac4d02b1183b1afb6a91340840     ? ./concatMapSep.dhall , concatSep =-      ./concatSep.dhall sha256:e4401d69918c61b92a4c0288f7d60a6560ca99726138ed8ebc58dca2cd205e58+      missing+        sha256:e4401d69918c61b92a4c0288f7d60a6560ca99726138ed8ebc58dca2cd205e58     ? ./concatSep.dhall , default =-      ./default.dhall sha256:f532c8891b1e427d90a6cc07cf7e793a4c84b0765e1bfe69f186ee2ec91c1edf+      missing+        sha256:f532c8891b1e427d90a6cc07cf7e793a4c84b0765e1bfe69f186ee2ec91c1edf     ? ./default.dhall , defaultMap =-      ./defaultMap.dhall sha256:3a3fa1264f6198800c27483cb144de2c5366484876d60b9c739a710ce0288588+      missing+        sha256:3a3fa1264f6198800c27483cb144de2c5366484876d60b9c739a710ce0288588     ? ./defaultMap.dhall+, lowerASCII =+      missing+        sha256:26b076651120b907e869396bd3dc16271f2e12433062b2f26f296968a69515e7+    ? ./lowerASCII.dhall+, replace =+      missing+        sha256:7d132df0e091a43817bba8afa06d1bb487ee51c091430404ad6f8c78bc0328a6+    ? ./replace.dhall , replicate =-      ./replicate.dhall sha256:1b398b1d464b3a6c7264a690ac3cacb443b5683b43348c859d68e7c2cb925c4f+      missing+        sha256:1b398b1d464b3a6c7264a690ac3cacb443b5683b43348c859d68e7c2cb925c4f     ? ./replicate.dhall+, shell-escape =+      missing+        sha256:d53521b3f478cb18a7d63730bc0e3153c2124b70d6ac9a1f610ce7db67cfc7a2+    ? ./shell-escape.dhall , show =-      ./show.dhall sha256:c9dc5de3e5f32872dbda57166804865e5e80785abe358ff61f1d8ac45f1f4784+      missing+        sha256:c9dc5de3e5f32872dbda57166804865e5e80785abe358ff61f1d8ac45f1f4784     ? ./show.dhall , spaces =-      ./spaces.dhall sha256:fccfd4f26601e006bf6a79ca948dbd37c676cdd0db439554447320293d23b3dc+      missing+        sha256:fccfd4f26601e006bf6a79ca948dbd37c676cdd0db439554447320293d23b3dc     ? ./spaces.dhall+, upperASCII =+      missing+        sha256:45ae4fbd814b0474e65c28a4ee92b23b979892fa5bb73730bc99675ae790ca29+    ? ./upperASCII.dhall }
dhall-lang/Prelude/Text/replicate view
@@ -1,2 +1,3 @@-  ./replicate.dhall sha256:1b398b1d464b3a6c7264a690ac3cacb443b5683b43348c859d68e7c2cb925c4f+  missing+    sha256:1b398b1d464b3a6c7264a690ac3cacb443b5683b43348c859d68e7c2cb925c4f ? ./replicate.dhall
dhall-lang/Prelude/Text/replicate.dhall view
@@ -1,11 +1,12 @@ --| Build a Text by copying the given Text the specified number of times- let concat =-        ./concat.dhall sha256:731265b0288e8a905ecff95c97333ee2db614c39d69f1514cb8eed9259745fc0+        missing+          sha256:731265b0288e8a905ecff95c97333ee2db614c39d69f1514cb8eed9259745fc0       ? ./concat.dhall  let List/replicate =-        ../List/replicate.dhall sha256:d4250b45278f2d692302489ac3e78280acb238d27541c837ce46911ff3baa347+        missing+          sha256:d4250b45278f2d692302489ac3e78280acb238d27541c837ce46911ff3baa347       ? ../List/replicate.dhall  let replicate
+ dhall-lang/Prelude/Text/shell-escape.dhall view
@@ -0,0 +1,16 @@+{-|+Escape a Text value such that it can be used safely in shells.+The escaping is done by replacing all `'` with `'"'"'` and wraps that string in+single quotes.++This works for all POSIX-compliant shells and some other shells like csh.+-}+let shell-escape+    : Text -> Text+    = \(xs : Text) -> "'${Text/replace "'" "'\"'\"'" xs}'"++let example0 = assert : shell-escape "foo" === "'foo'"++let example1 = assert : shell-escape "foo'bar" === "'foo'\"'\"'bar'"++in  shell-escape
dhall-lang/Prelude/Text/show view
@@ -1,2 +1,3 @@-  ./show.dhall sha256:c9dc5de3e5f32872dbda57166804865e5e80785abe358ff61f1d8ac45f1f4784+  missing+    sha256:c9dc5de3e5f32872dbda57166804865e5e80785abe358ff61f1d8ac45f1f4784 ? ./show.dhall
dhall-lang/Prelude/Text/spaces view
@@ -1,2 +1,3 @@-  ./spaces.dhall sha256:fccfd4f26601e006bf6a79ca948dbd37c676cdd0db439554447320293d23b3dc+  missing+    sha256:fccfd4f26601e006bf6a79ca948dbd37c676cdd0db439554447320293d23b3dc ? ./spaces.dhall
dhall-lang/Prelude/Text/spaces.dhall view
@@ -4,9 +4,9 @@ This function is particularly helpful when trying to generate Text where whitespace is significant, i.e. with nested indentation. -}- let replicate =-        ./replicate.dhall sha256:1b398b1d464b3a6c7264a690ac3cacb443b5683b43348c859d68e7c2cb925c4f+        missing+          sha256:1b398b1d464b3a6c7264a690ac3cacb443b5683b43348c859d68e7c2cb925c4f       ? ./replicate.dhall  let spaces
+ dhall-lang/Prelude/Text/upperASCII.dhall view
@@ -0,0 +1,56 @@+{-|+Uppercase all ASCII characters++Note that this will also uppercase decomposed Unicode characters that contain+codepoints in the ASCII range+-}+let upperASCII+    : Text → Text+    = List/fold+        (Text → Text)+        [ Text/replace "a" "A"+        , Text/replace "b" "B"+        , Text/replace "c" "C"+        , Text/replace "d" "D"+        , Text/replace "e" "E"+        , Text/replace "f" "F"+        , Text/replace "g" "G"+        , Text/replace "h" "H"+        , Text/replace "i" "I"+        , Text/replace "j" "J"+        , Text/replace "k" "K"+        , Text/replace "l" "L"+        , Text/replace "m" "M"+        , Text/replace "n" "N"+        , Text/replace "o" "O"+        , Text/replace "p" "P"+        , Text/replace "q" "Q"+        , Text/replace "r" "R"+        , Text/replace "s" "S"+        , Text/replace "t" "T"+        , Text/replace "u" "U"+        , Text/replace "v" "V"+        , Text/replace "w" "W"+        , Text/replace "x" "X"+        , Text/replace "y" "Y"+        , Text/replace "z" "Z"+        ]+        Text+        (λ(replacement : Text → Text) → replacement)++let example0 = assert : upperASCII "ABCdef" ≡ "ABCDEF"++let -- This does not uppercase precomposed Unicode characters+    --+    -- • The `á` in the following example is U+00E1+    example1 =+      assert : upperASCII "á" ≡ "á"++let -- … but this does uppercase decomposed Unicode characters+    --+    -- • The `Á` in the following example is U+0041 U+0301+    -- • The `á` in the following example is U+0061 U+0301+    example1 =+      assert : upperASCII "á" ≡ "Á"++in  upperASCII
+ dhall-lang/Prelude/Time/package.dhall view
@@ -0,0 +1,5 @@+{ show =+      missing+        sha256:8cabfe35dd0ee25ca65708105e860cbf4b789e0d73134aa905580799e2a46719+    ? ./show.dhall+}
+ dhall-lang/Prelude/Time/show.dhall view
@@ -0,0 +1,15 @@+{-+Render a `Time` as `Text` using the same representation as Dhall source code+(i.e. `hh:mm:ss`)+-}+let show+    : Time → Text+    = Time/show++let example0 = assert : show 03:15:47.90 ≡ "03:15:47.90"++let example1 = assert : show 00:00:00 ≡ "00:00:00"++let example2 = assert : show 11:59:59 ≡ "11:59:59"++in  show
+ dhall-lang/Prelude/TimeZone/package.dhall view
@@ -0,0 +1,5 @@+{ show =+      missing+        sha256:d183361f1c4c656bad3b170ec8b8d6705f564faebf94e4ef10c76061104ff061+    ? ./show.dhall+}
+ dhall-lang/Prelude/TimeZone/show.dhall view
@@ -0,0 +1,15 @@+{-+Render a `TimeZone` as `Text` using the same representation as Dhall source code+(i.e. `±HH:MM`)+-}+let show+    : TimeZone → Text+    = TimeZone/show++let example0 = assert : show +07:00 ≡ "+07:00"++let example1 = assert : show +00:00 ≡ "+00:00"++let example2 = assert : show -05:00 ≡ "-05:00"++in  show
dhall-lang/Prelude/XML/Type view
@@ -1,2 +1,3 @@-  ./Type.dhall sha256:461930f3aab769ba537d1a4fd71f411504b0c8d1c1a78d65177be8ded0df8a5c+  missing+    sha256:ab91a0edaf0513e0083b1dfae5efa160adc99b0e589775a4a699ab77cce528a9 ? ./Type.dhall
dhall-lang/Prelude/XML/Type.dhall view
@@ -15,6 +15,8 @@  → λ ( xml      : { text :            Text → XML+       , rawText :+           Text → XML        , element :              { attributes :                  List { mapKey : Text, mapValue : Text }@@ -44,12 +46,12 @@    } ``` -}- let XML/Type     : Type     = ∀(XML : Type) →       ∀ ( xml         : { text : Text → XML+          , rawText : Text → XML           , element :               { attributes : List { mapKey : Text, mapValue : Text }               , content : List XML
dhall-lang/Prelude/XML/attribute view
@@ -1,2 +1,3 @@-  ./attribute.dhall sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc+  missing+    sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc ? ./attribute.dhall
dhall-lang/Prelude/XML/attribute.dhall view
@@ -1,5 +1,4 @@ --| Builds a key-value record with a Text key and value.- let attribute     : Text → Text → { mapKey : Text, mapValue : Text }     = λ(key : Text) → λ(value : Text) → { mapKey = key, mapValue = value }
dhall-lang/Prelude/XML/element view
@@ -1,2 +1,3 @@-  ./element.dhall sha256:e0b948053c8cd8ccca9c39244d89e3f42db43d222531c18151551dfc75208b4b+  missing+    sha256:79266d604e147caf37e985581523b684f7bac66de0c93dd828841df3dfc445f9 ? ./element.dhall
dhall-lang/Prelude/XML/element.dhall view
@@ -18,14 +18,14 @@ = "<foo><bar n=\"1\"/><baz n=\"2\"/></foo>" ``` -}-- let XML =-        ./Type.dhall sha256:461930f3aab769ba537d1a4fd71f411504b0c8d1c1a78d65177be8ded0df8a5c+        missing+          sha256:ab91a0edaf0513e0083b1dfae5efa160adc99b0e589775a4a699ab77cce528a9       ? ./Type.dhall  let List/map =-        ../List/map.dhall sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680+        missing+          sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680       ? ../List/map.dhall  let Args =@@ -41,6 +41,7 @@       λ(XML : Type) →       λ ( xml         : { text : Text → XML+          , rawText : Text → XML           , element :               { attributes : List { mapKey : Text, mapValue : Text }               , content : List XML
dhall-lang/Prelude/XML/emptyAttributes view
@@ -1,2 +1,3 @@-  ./emptyAttributes.dhall sha256:11b86e2d3f3c75d47a1d580213d2a03fd2c36d64f3e9b6381de0ba23472f64d5+  missing+    sha256:11b86e2d3f3c75d47a1d580213d2a03fd2c36d64f3e9b6381de0ba23472f64d5 ? ./emptyAttributes.dhall
dhall-lang/Prelude/XML/emptyAttributes.dhall view
@@ -1,3 +1,2 @@ --| Create an empty XML attribute List.- [] : List { mapKey : Text, mapValue : Text }
dhall-lang/Prelude/XML/leaf view
@@ -1,2 +1,3 @@-  ./leaf.dhall sha256:4383e4fc4bf6a29ac2052776972eb59d5355a1cd067cded80d4ff32840969261+  missing+    sha256:5dcedf79a3664a362479f470220bb2f4932facde657c285fd8a3c24ab137c506 ? ./leaf.dhall
dhall-lang/Prelude/XML/leaf.dhall view
@@ -9,13 +9,14 @@ = "<foobar/>" ``` -}- let XML =-        ./Type.dhall sha256:461930f3aab769ba537d1a4fd71f411504b0c8d1c1a78d65177be8ded0df8a5c+        missing+          sha256:ab91a0edaf0513e0083b1dfae5efa160adc99b0e589775a4a699ab77cce528a9       ? ./Type.dhall  let element =-        ./element.dhall sha256:e0b948053c8cd8ccca9c39244d89e3f42db43d222531c18151551dfc75208b4b+        missing+          sha256:79266d604e147caf37e985581523b684f7bac66de0c93dd828841df3dfc445f9       ? ./element.dhall  let leaf
dhall-lang/Prelude/XML/package.dhall view
@@ -1,22 +1,33 @@ { Type =-      ./Type.dhall sha256:461930f3aab769ba537d1a4fd71f411504b0c8d1c1a78d65177be8ded0df8a5c+      missing+        sha256:ab91a0edaf0513e0083b1dfae5efa160adc99b0e589775a4a699ab77cce528a9     ? ./Type.dhall , attribute =-      ./attribute.dhall sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc+      missing+        sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc     ? ./attribute.dhall , render =-      ./render.dhall sha256:8d034f7f97cded14a96147565d489be840e5678480d175b962b2600d85a3230e+      missing+        sha256:395c293702c85d99f6f2b461f3eee320f9fe5749c320c2e8b9ea799a7d210b66     ? ./render.dhall , element =-      ./element.dhall sha256:e0b948053c8cd8ccca9c39244d89e3f42db43d222531c18151551dfc75208b4b+      missing+        sha256:79266d604e147caf37e985581523b684f7bac66de0c93dd828841df3dfc445f9     ? ./element.dhall , leaf =-      ./leaf.dhall sha256:4383e4fc4bf6a29ac2052776972eb59d5355a1cd067cded80d4ff32840969261+      missing+        sha256:5dcedf79a3664a362479f470220bb2f4932facde657c285fd8a3c24ab137c506     ? ./leaf.dhall , text =-      ./text.dhall sha256:c83cd721d32d7dc28c04ce429c0cb22812639e572637ec348578a58ffb68844f+      missing+        sha256:a59670560a08bfc815893dee1f3eae21a5252400f8a619d1cd7bdd9f48eea2ab     ? ./text.dhall+, rawText =+      missing+        sha256:2af9d72c151677d4110039e361b7e9faaf2947e6c9d29aa72aea351ad797e05d+    ? ./rawText.dhall , emptyAttributes =-      ./emptyAttributes.dhall sha256:11b86e2d3f3c75d47a1d580213d2a03fd2c36d64f3e9b6381de0ba23472f64d5+      missing+        sha256:11b86e2d3f3c75d47a1d580213d2a03fd2c36d64f3e9b6381de0ba23472f64d5     ? ./emptyAttributes.dhall }
+ dhall-lang/Prelude/XML/rawText.dhall view
@@ -0,0 +1,40 @@+{-|+Create a Text value to be inserted into an XML element as content with no+character escaping.++```+let XML = ./package.dhall++in  XML.render+    ( XML.element+      { name = "location"+      , attributes = XML.emptyAttributes+      , content = [ XML.rawText "<bar n=\"1\"/>" ]+      }+    )+= "<foo><bar n=\"1\"/></foo>"+```+-}+let XML =+        missing+          sha256:ab91a0edaf0513e0083b1dfae5efa160adc99b0e589775a4a699ab77cce528a9+      ? ./Type.dhall++let rawText+    : Text → XML+    = λ(d : Text) →+      λ(XML : Type) →+      λ ( xml+        : { text : Text → XML+          , rawText : Text → XML+          , element :+              { attributes : List { mapKey : Text, mapValue : Text }+              , content : List XML+              , name : Text+              } →+                XML+          }+        ) →+        xml.rawText d++in  rawText
dhall-lang/Prelude/XML/render view
@@ -1,2 +1,3 @@-  ./render.dhall sha256:8d034f7f97cded14a96147565d489be840e5678480d175b962b2600d85a3230e+  missing+    sha256:395c293702c85d99f6f2b461f3eee320f9fe5749c320c2e8b9ea799a7d210b66 ? ./render.dhall
dhall-lang/Prelude/XML/render.dhall view
@@ -1,10 +1,6 @@ {-| 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.- For indentation and schema validation, see the `xmllint` utility bundled with libxml2. @@ -12,7 +8,7 @@ let XML = ./package.dhall  in  XML.render-    ( XML.node+    ( XML.element       { name = "foo"       , attributes = [ XML.attribute "a" "x", XML.attribute "b" (Natural/show 2) ]       , content = [ XML.leaf { name = "bar", attributes = XML.emptyAttributes } ]@@ -22,29 +18,65 @@ ```  -}- let XML =-        ./Type.dhall sha256:461930f3aab769ba537d1a4fd71f411504b0c8d1c1a78d65177be8ded0df8a5c+        missing+          sha256:ab91a0edaf0513e0083b1dfae5efa160adc99b0e589775a4a699ab77cce528a9       ? ./Type.dhall  let Text/concatMap =-        ../Text/concatMap.dhall sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f+        missing+          sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f       ? ../Text/concatMap.dhall  let Text/concat =-        ../Text/concat.dhall sha256:731265b0288e8a905ecff95c97333ee2db614c39d69f1514cb8eed9259745fc0+        missing+          sha256:731265b0288e8a905ecff95c97333ee2db614c39d69f1514cb8eed9259745fc0       ? ../Text/concat.dhall +let element =+        missing+          sha256:79266d604e147caf37e985581523b684f7bac66de0c93dd828841df3dfc445f9+      ? ./element.dhall++let text =+        missing+          sha256:a59670560a08bfc815893dee1f3eae21a5252400f8a619d1cd7bdd9f48eea2ab+      ? ./text.dhall++let emptyAttributes =+        missing+          sha256:11b86e2d3f3c75d47a1d580213d2a03fd2c36d64f3e9b6381de0ba23472f64d5+      ? ./emptyAttributes.dhall+ let Attr = { mapKey : Text, mapValue : Text } -let renderAttr = λ(x : Attr) → " ${x.mapKey}=\"${x.mapValue}\""+let esc = λ(x : Text) → λ(y : Text) → Text/replace x "&${y};" +let `escape&` = esc "&" "amp"++let `escape<` = esc "<" "lt"++let `escape>` = esc ">" "gt"++let `escape'` = esc "'" "apos"++let `escape"` = esc "\"" "quot"++let escapeCommon = λ(text : Text) → `escape<` (`escape&` text)++let escapeAttr = λ(text : Text) → `escape"` (`escape'` (escapeCommon text))++let escapeText = λ(text : Text) → `escape>` (escapeCommon text)++let renderAttr = λ(x : Attr) → " ${x.mapKey}=\"${escapeAttr x.mapValue}\""+ let render     : XML → Text     = λ(x : XML) →         x           Text-          { text = λ(d : Text) → d+          { text = escapeText+          , rawText = λ(t : Text) → t           , element =               λ ( elem                 : { attributes : List { mapKey : Text, mapValue : Text }@@ -60,5 +92,49 @@                           else  ">${Text/concat elem.content}</${elem.name}>"                         )           }++let simple =+      λ(name : Text) →+      λ(content : List XML) →+        element { name, attributes = emptyAttributes, content }++let example0 =+        assert+      :   render+            ( simple+                "note"+                [ simple "to" [ text "Tove" ]+                , simple "from" [ text "Jani" ]+                , simple "heading" [ text "Reminder" ]+                , simple "body" [ text "Don't forget me this weekend!" ]+                ]+            )+        ≡ Text/replace+            "\n"+            ""+            ''+            <note>+            <to>Tove</to>+            <from>Jani</from>+            <heading>Reminder</heading>+            <body>Don't forget me this weekend!</body>+            </note>+            ''++let example1 =+        assert+      :   render+            ( element+                { name = "escape"+                , attributes = toMap { attribute = "<>'\"&" }+                , content = [ text "<>'\"&" ]+                }+            )+        ≡ Text/replace+            "\n"+            ""+            ''+            <escape attribute="&lt;>&apos;&quot;&amp;">&lt;&gt;'"&amp;</escape>+            ''  in  render
dhall-lang/Prelude/XML/text view
@@ -1,2 +1,3 @@-  ./text.dhall sha256:c83cd721d32d7dc28c04ce429c0cb22812639e572637ec348578a58ffb68844f+  missing+    sha256:a59670560a08bfc815893dee1f3eae21a5252400f8a619d1cd7bdd9f48eea2ab ? ./text.dhall
dhall-lang/Prelude/XML/text.dhall view
@@ -5,7 +5,7 @@ let XML = ./package.dhall  in  XML.render-    ( XML.node+    ( XML.element       { name = "location"       , attributes = XML.emptyAttributes       , content = [ XML.text "/foo/bar" ]@@ -14,9 +14,9 @@ = "<location>/foo/bar</location>" ``` -}- let XML =-        ./Type.dhall sha256:461930f3aab769ba537d1a4fd71f411504b0c8d1c1a78d65177be8ded0df8a5c+        missing+          sha256:ab91a0edaf0513e0083b1dfae5efa160adc99b0e589775a4a699ab77cce528a9       ? ./Type.dhall  let text@@ -25,6 +25,7 @@       λ(XML : Type) →       λ ( xml         : { text : Text → XML+          , rawText : Text → XML           , element :               { attributes : List { mapKey : Text, mapValue : Text }               , content : List XML
dhall-lang/Prelude/package.dhall view
@@ -1,40 +1,73 @@ { Bool =-      ./Bool/package.dhall sha256:7ee950e7c2142be5923f76d00263e536b71d96cb9c190d7743c1679501ddeb0a+      missing+        sha256:dde2b9b71afdd26878c06e90cd2cde4488063457d5fbe30e02baed3bec5eede6     ? ./Bool/package.dhall+, Date =+      missing+        sha256:fc0c5efc924fa99aa8e5dea5d78c3dc1a24cb550028342b90149ea78cb5ca873+    ? ./Date/package.dhall , Double =-      ./Double/package.dhall sha256:b8d20ab3216083622ae371fb42a6732bc67bb2d66e84989c8ddba7556a336cf7+      missing+        sha256:b8d20ab3216083622ae371fb42a6732bc67bb2d66e84989c8ddba7556a336cf7     ? ./Double/package.dhall , Function =-      ./Function/package.dhall sha256:6d17cf0fd4fabe1737fb117f87c04b8ff82b299915a5b673c0a543b134b8fffe+      missing+        sha256:f4ca848f69034f9d7a74e12c556c3a3396966c1de3a9427a102d1aff4580192f     ? ./Function/package.dhall , Integer =-      ./Integer/package.dhall sha256:d1a572ca3a764781496847e4921d7d9a881c18ffcfac6ae28d0e5299066938a0+      missing+        sha256:d1a572ca3a764781496847e4921d7d9a881c18ffcfac6ae28d0e5299066938a0     ? ./Integer/package.dhall+, JSON =+      missing+        sha256:5f98b7722fd13509ef448b075e02b9ff98312ae7a406cf53ed25012dbc9990ac+    ? ./JSON/package.dhall , List =-      ./List/package.dhall sha256:547cd881988c6c5e3673ae80491224158e93a4627690db0196cb5efbbf00d2ba+      missing+        sha256:26d1b4cd800219d8b67043c638926aa6e5517ea74a0bd3e371974514621bca04     ? ./List/package.dhall , Location =-      ./Location/package.dhall sha256:0eb4e4a60814018009c720f6820aaa13cf9491eb1b09afb7b832039c6ee4d470+      missing+        sha256:0eb4e4a60814018009c720f6820aaa13cf9491eb1b09afb7b832039c6ee4d470     ? ./Location/package.dhall , Map =-      ./Map/package.dhall sha256:c6602939eb75ddaf43e75a37e1f27ace97e03685ceb9d77605b4372547f7cfa8+      missing+        sha256:c5e79a9de642644a09b96a2ec3147c5d8662b7926f09610e751c0c0f6ed0b30a     ? ./Map/package.dhall , Monoid =-      ./Monoid.dhall sha256:26fafa098600ef7a54ef9dba5ada416bbbdd21df1af306c052420c61553ad4af+      missing+        sha256:26fafa098600ef7a54ef9dba5ada416bbbdd21df1af306c052420c61553ad4af     ? ./Monoid.dhall , Natural =-      ./Natural/package.dhall sha256:ee9ed2b28a417ed4e9a0c284801b928bf91b3fbdc1a68616347678c1821f1ddf+      missing+        sha256:ee9ed2b28a417ed4e9a0c284801b928bf91b3fbdc1a68616347678c1821f1ddf     ? ./Natural/package.dhall+, NonEmpty =+      missing+        sha256:c24686a230a4b3cd51e5a57cd4510b4f8242f813d7823d41bac5954e7af56f7a+    ? ./NonEmpty/package.dhall+, Operator =+      missing+        sha256:861f724704a7b4755c96f173e54d03f314492a2d046723404c31ff612b7bf2e6+    ? ./Operator/package.dhall , Optional =-      ./Optional/package.dhall sha256:4324b2bf84ded40f67485f14355e4cb7b237a8f173e713c791ec44cebebc552c+      missing+        sha256:74331dfe59c09db65edc7ec4498bff92473c8c06d92752f9470d26e25f91320c     ? ./Optional/package.dhall-, JSON =-      ./JSON/package.dhall sha256:79dfc281a05bc7b78f927e0da0c274ee5709b1c55c9e5f59499cb28e9d6f3ec0-    ? ./JSON/package.dhall , Text =-      ./Text/package.dhall sha256:819a967038fbf6f28cc289fa2651e42835f70b326210c86e51acf48f46f913d8+      missing+        sha256:79b671a70ac459b799a53bbb8a383cc8b81b40421745c54bf0fb1143168cbd6f     ? ./Text/package.dhall+, Time =+      missing+        sha256:6715c4c71a113429fef8b94e4561a93c288942dad9dfd75ac545de96c5b5652a+    ? ./Time/package.dhall+, TimeZone =+      missing+        sha256:c17fd403c637856f34c8287168b92974e8c1a3a7331967f75276d179057084fd+    ? ./TimeZone/package.dhall , XML =-      ./XML/package.dhall sha256:137e7b106b2e9743970e5d37b21a165f2e40f56ab593a4dd10605c9acd686fc6+      missing+        sha256:2e111f0952087d42072b059f0bf4c95861a46bffa67ad4c8c39086edf405f32e     ? ./XML/package.dhall }
+ dhall-lang/tests/binary-decode/success/unit/BytesA.dhallb view

binary file changed (absent → 114 bytes)

+ dhall-lang/tests/binary-decode/success/unit/BytesB.dhall view
@@ -0,0 +1,23 @@+[ 0x"00"+, 0x"01"+, 0x"02"+, 0x"03"+, 0x"04"+, 0x"05"+, 0x"06"+, 0x"07"+, 0x"08"+, 0x"09"+, 0x"0a"+, 0x"0b"+, 0x"0c"+, 0x"0d"+, 0x"0e"+, 0x"0f"+, 0x"0A"+, 0x"0B"+, 0x"0C"+, 0x"0D"+, 0x"0E"+, 0x"0F"+]
+ dhall-lang/tests/binary-decode/success/unit/DateA.dhallb view
@@ -0,0 +1,1 @@+„Ð
+ dhall-lang/tests/binary-decode/success/unit/DateB.dhall view
@@ -0,0 +1,1 @@+2000-01-01
+ dhall-lang/tests/binary-decode/success/unit/TimeA.dhallb view

binary file changed (absent → 9 bytes)

+ dhall-lang/tests/binary-decode/success/unit/TimeB.dhall view
@@ -0,0 +1,1 @@+12:00:00
+ dhall-lang/tests/binary-decode/success/unit/TimeZoneA.dhallb view

binary file changed (absent → 6 bytes)

+ dhall-lang/tests/binary-decode/success/unit/TimeZoneB.dhall view
@@ -0,0 +1,1 @@++08:00
+ dhall-lang/tests/import/data/cors/AllowedAll.dhall view
@@ -0,0 +1,1 @@+https://test.dhall-lang.org/cors/AllowedAll.dhall
+ dhall-lang/tests/import/data/cors/Empty.dhall view
@@ -0,0 +1,1 @@+https://test.dhall-lang.org/cors/Empty.dhall
+ dhall-lang/tests/import/data/cors/NoCORS.dhall view
@@ -0,0 +1,1 @@+https://test.dhall-lang.org/cors/NoCORS.dhall
+ dhall-lang/tests/import/data/cors/Null.dhall view
@@ -0,0 +1,1 @@+https://test.dhall-lang.org/cors/Null.dhall
+ dhall-lang/tests/import/data/cors/OnlyGithub.dhall view
@@ -0,0 +1,1 @@+https://test.dhall-lang.org/cors/OnlyGithub.dhall
+ dhall-lang/tests/import/data/cors/OnlyOther.dhall view
@@ -0,0 +1,1 @@+https://test.dhall-lang.org/cors/OnlyOther.dhall
+ dhall-lang/tests/import/data/cors/OnlySelf.dhall view
@@ -0,0 +1,1 @@+https://test.dhall-lang.org/cors/OnlySelf.dhall
+ dhall-lang/tests/import/data/cors/Prelude.dhall view
@@ -0,0 +1,1 @@+https://prelude.dhall-lang.org/List/length
+ dhall-lang/tests/import/data/cors/SelfImportAbsolute.dhall view
@@ -0,0 +1,1 @@+https://test.dhall-lang.org/cors/SelfImportAbsolute.dhall
+ dhall-lang/tests/import/data/cors/SelfImportRelative.dhall view
@@ -0,0 +1,1 @@+https://test.dhall-lang.org/cors/SelfImportRelative.dhall
dhall-lang/tests/import/data/cycle.dhall view
@@ -1,1 +1,1 @@-../failure/cycle.dhall+../failure/unit/Cycle.dhall
+ dhall-lang/tests/import/data/doesNotParse.dhall view
@@ -0,0 +1,1 @@+[
+ dhall-lang/tests/import/data/example.bin view
@@ -0,0 +1,1 @@+#Eg‰«Íï
+ dhall-lang/tests/import/data/userAgent.dhall view
@@ -0,0 +1,1 @@+"Dhall (from import)"
− dhall-lang/tests/import/failure/cycle.dhall
@@ -1,1 +0,0 @@-../data/cycle.dhall
− dhall-lang/tests/import/failure/hashMismatch.dhall
@@ -1,1 +0,0 @@-../data/simple.dhall sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
− dhall-lang/tests/import/failure/importBoundary.dhall
@@ -1,1 +0,0 @@-\(x: Bool) -> ../data/importBoundary.dhall
− dhall-lang/tests/import/failure/missing.dhall
@@ -1,1 +0,0 @@-missing
+ dhall-lang/tests/import/failure/originHeadersFromRemote.dhall view
@@ -0,0 +1,1 @@+https://httpbin.org/user-agent as Text
+ dhall-lang/tests/import/failure/originHeadersFromRemoteENV.dhall view
@@ -0,0 +1,11 @@+-- Use of a remote import causes Cyclic Import on env:DHALL_HEADERS+toMap+  { DHALL_HEADERS =+      ''+      toMap {+        `httpbin.org:443` = toMap {+          `User-Agent` = http://example.com as Text+        }+      }+      ''+  }
− dhall-lang/tests/import/failure/referentiallyInsane.dhall
@@ -1,13 +0,0 @@-{- The following remote import attempts to import an environment variable, which-   must be disallowed by the referential sanity check--   One reason for doing this is to protect against remote imports exfiltrating-   environment variables (such as via custom headers).  Only referentially-   opaque imports (i.e. local imports) have permission to refer to other-   referentially opaque imports in order to protect against this attack.--   The referential sanity check also ensures that remote imports are-   referentially transparent.  Or in other words, any import that is globally-   addressable must have a meaning that is not context-sensitive.--}-https://raw.githubusercontent.com/dhall-lang/dhall-lang/master/tests/import/data/referentiallyOpaque.dhall
+ dhall-lang/tests/import/failure/unit/404.dhall view
@@ -0,0 +1,1 @@+https://test.dhall-lang.org/nonexistent-file.dhall
+ dhall-lang/tests/import/failure/unit/Cycle.dhall view
@@ -0,0 +1,1 @@+../../data/cycle.dhall
+ dhall-lang/tests/import/failure/unit/DontRecoverCycle.dhall view
@@ -0,0 +1,1 @@+../../data/cycle.dhall ? 0
+ dhall-lang/tests/import/failure/unit/DontRecoverHashMismatch.dhall view
@@ -0,0 +1,3 @@+-- This fails because the `?` operator does not recover from integrity check+-- failures+../../data/simple.dhall sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? 0
+ dhall-lang/tests/import/failure/unit/DontRecoverParseError.dhall view
@@ -0,0 +1,1 @@+../../data/doesNotParse.dhall ? 0
+ dhall-lang/tests/import/failure/unit/DontRecoverTypeError.dhall view
@@ -0,0 +1,1 @@+../../data/doesNotTypecheck.dhall ? 0
+ dhall-lang/tests/import/failure/unit/EnvFromRemote.dhall view
@@ -0,0 +1,13 @@+{- The following remote import attempts to import an environment variable, which+   must be disallowed by the referential sanity check++   One reason for doing this is to protect against remote imports exfiltrating+   environment variables (such as via custom headers).  Only referentially+   opaque imports (i.e. local imports) have permission to refer to other+   referentially opaque imports in order to protect against this attack.++   The referential sanity check also ensures that remote imports are+   referentially transparent.  Or in other words, any import that is globally+   addressable must have a meaning that is not context-sensitive.+-}+https://raw.githubusercontent.com/dhall-lang/dhall-lang/master/tests/import/data/referentiallyOpaque.dhall
+ dhall-lang/tests/import/failure/unit/FileMissing.dhall view
@@ -0,0 +1,1 @@+./not-a-file.dhall
+ dhall-lang/tests/import/failure/unit/HashMismatch.dhall view
@@ -0,0 +1,1 @@+../data/simple.dhall sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ dhall-lang/tests/import/failure/unit/HashMismatch2.dhall view
@@ -0,0 +1,2 @@+-- This ensures that even if the file gets imported without hash first, the hash check is not skipped later+../../data/simple.dhall + ../../data/simple.dhall sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ../../data/simple.dhall
+ dhall-lang/tests/import/failure/unit/Missing.dhall view
@@ -0,0 +1,1 @@+missing
+ dhall-lang/tests/import/failure/unit/VarAcrossImportBoundary.dhall view
@@ -0,0 +1,1 @@+\(x: Bool) -> ../../data/importBoundary.dhall
+ dhall-lang/tests/import/failure/unit/cors/Empty.dhall view
@@ -0,0 +1,1 @@+https://raw.githubusercontent.com/dhall-lang/dhall-lang/5ff7ecd2411894dd9ce307dc23020987361d2d43/tests/import/data/cors/Empty.dhall
+ dhall-lang/tests/import/failure/unit/cors/NoCORS.dhall view
@@ -0,0 +1,1 @@+https://raw.githubusercontent.com/dhall-lang/dhall-lang/5ff7ecd2411894dd9ce307dc23020987361d2d43/tests/import/data/cors/NoCORS.dhall
+ dhall-lang/tests/import/failure/unit/cors/Null.dhall view
@@ -0,0 +1,1 @@+https://raw.githubusercontent.com/dhall-lang/dhall-lang/5ff7ecd2411894dd9ce307dc23020987361d2d43/tests/import/data/cors/Null.dhall
+ dhall-lang/tests/import/failure/unit/cors/OnlyOther.dhall view
@@ -0,0 +1,1 @@+https://raw.githubusercontent.com/dhall-lang/dhall-lang/5ff7ecd2411894dd9ce307dc23020987361d2d43/tests/import/data/cors/OnlyOther.dhall
+ dhall-lang/tests/import/failure/unit/cors/OnlySelf.dhall view
@@ -0,0 +1,1 @@+https://raw.githubusercontent.com/dhall-lang/dhall-lang/5ff7ecd2411894dd9ce307dc23020987361d2d43/tests/import/data/cors/OnlySelf.dhall
+ dhall-lang/tests/import/failure/unit/cors/TwoHops.dhall view
@@ -0,0 +1,1 @@+https://test.dhall-lang.org/cors/TwoHopsFail.dhall
+ dhall-lang/tests/import/home/hello.dhall view
@@ -0,0 +1,1 @@+"hello"
dhall-lang/tests/import/success/headerForwardingA.dhall view
@@ -1,16 +1,12 @@ {- This test verifies that header-forwarding works correctly for relative    imports within the same domain -   `test.dhall-lang.org` is the same as `prelude.dhall-lang.org` except that-   `test.dhall-lang.org` rejects all requests without a `Test` header.+   `test.dhall-lang.org/foo` returns `./bar` and `test.dhall-lang.org/foo`+   returns `True`, and both URLs reject all requests without a `Test` header.     This test requires that the initial import to-   `https://test.dhall-lang.org/Bool/package.dhall` forwards the `Test` header-   to the transitive relative imports of `https://test.dhall-lang.org/Bool/*` in+   `https://test.dhall-lang.org/foo` forwards the `Test` header+   to the transitive relative import of `https://test.dhall-lang.org/bar` in    order to succeed.--   Note: You will need to update this test whenever the `Bool` package in the-   Prelude changes (sorry) -}-https://test.dhall-lang.org/Bool/package.dhall-  using [ { mapKey = "Test", mapValue = "Example" } ]+https://test.dhall-lang.org/foo using (toMap { Test = "Example" })
dhall-lang/tests/import/success/headerForwardingB.dhall view
@@ -1,26 +1,1 @@-{ and =-      λ(xs : List Bool)-    → List/fold Bool xs Bool (λ(l : Bool) → λ(r : Bool) → l && r) True-, build =-      λ(f : ∀(bool : Type) → ∀(true : bool) → ∀(false : bool) → bool)-    → f Bool True False-, even =-      λ(xs : List Bool)-    → List/fold Bool xs Bool (λ(x : Bool) → λ(y : Bool) → x == y) True-, fold =-      λ(b : Bool)-    → λ(bool : Type)-    → λ(true : bool)-    → λ(false : bool)-    → if b then true else false-, not =-    λ(b : Bool) → b == False-, odd =-      λ(xs : List Bool)-    → List/fold Bool xs Bool (λ(x : Bool) → λ(y : Bool) → x != y) False-, or =-      λ(xs : List Bool)-    → List/fold Bool xs Bool (λ(l : Bool) → λ(r : Bool) → l || r) False-, show =-    λ(b : Bool) → if b then "True" else "False"-}+True
+ dhall-lang/tests/import/success/originHeadersA.dhall view
@@ -0,0 +1,1 @@+https://httpbin.org/user-agent as Text
+ dhall-lang/tests/import/success/originHeadersB.dhall view
@@ -0,0 +1,5 @@+''+{+  "user-agent": "Dhall"+}+''
+ dhall-lang/tests/import/success/originHeadersENV.dhall view
@@ -0,0 +1,10 @@+toMap+  { DHALL_HEADERS =+      ''+      toMap {+        `httpbin.org:443` = toMap {+          `User-Agent` = "Dhall"+        }+      }+      ''+  }
+ dhall-lang/tests/import/success/originHeadersImportA.dhall view
@@ -0,0 +1,1 @@+https://httpbin.org/user-agent as Text
+ dhall-lang/tests/import/success/originHeadersImportB.dhall view
@@ -0,0 +1,5 @@+''+{+  "user-agent": "Dhall (from import)"+}+''
+ dhall-lang/tests/import/success/originHeadersImportENV.dhall view
@@ -0,0 +1,10 @@+toMap+  { DHALL_HEADERS =+      ''+      toMap {+        `httpbin.org:443` = toMap {+          `User-Agent` = ./dhall-lang/tests/import/data/userAgent.dhall+        }+      }+      ''+  }
+ dhall-lang/tests/import/success/originHeadersImportFromEnvA.dhall view
@@ -0,0 +1,1 @@+https://httpbin.org/user-agent as Text
+ dhall-lang/tests/import/success/originHeadersImportFromEnvB.dhall view
@@ -0,0 +1,5 @@+''+{+  "user-agent": "Dhall (from env)"+}+''
+ dhall-lang/tests/import/success/originHeadersImportFromEnvENV.dhall view
@@ -0,0 +1,11 @@+toMap+  { DHALL_HEADERS =+      ''+      toMap {+        `httpbin.org:443` = toMap {+          `User-Agent` = env:USER_AGENT as Text+        }+      }+      ''+      , USER_AGENT = "Dhall (from env)"+  }
+ dhall-lang/tests/import/success/originHeadersOverrideA.dhall view
@@ -0,0 +1,3 @@+https://httpbin.org/user-agent+  using [ { mapKey = "User-Agent", mapValue = "inline-header" } ]+  as Text
+ dhall-lang/tests/import/success/originHeadersOverrideB.dhall view
@@ -0,0 +1,5 @@+''+{+  "user-agent": "user-header"+}+''
+ dhall-lang/tests/import/success/originHeadersOverrideENV.dhall view
@@ -0,0 +1,10 @@+toMap+  { DHALL_HEADERS =+      ''+      toMap {+        `httpbin.org:443` = toMap {+          `User-Agent` = "user-header"+        }+      }+      ''+  }
− dhall-lang/tests/import/success/unit/AlternativeHashMismatchA.dhall
@@ -1,1 +0,0 @@-../../data/simple.dhall sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ? 42
− dhall-lang/tests/import/success/unit/AlternativeHashMismatchB.dhall
@@ -1,1 +0,0 @@-42
− dhall-lang/tests/import/success/unit/AlternativeParseErrorA.dhall
@@ -1,1 +0,0 @@-../../data/example.txt ? 42
− dhall-lang/tests/import/success/unit/AlternativeParseErrorB.dhall
@@ -1,1 +0,0 @@-42
− dhall-lang/tests/import/success/unit/AlternativeTypeErrorA.dhall
@@ -1,1 +0,0 @@-../../data/doesNotTypecheck.dhall ? 42
− dhall-lang/tests/import/success/unit/AlternativeTypeErrorB.dhall
@@ -1,1 +0,0 @@-42
+ dhall-lang/tests/import/success/unit/AlternativeWithVariableA.dhall view
@@ -0,0 +1,1 @@+let x = 0 in (missing ? x)
+ dhall-lang/tests/import/success/unit/AlternativeWithVariableB.dhall view
@@ -0,0 +1,1 @@+let x = 0 in x
+ dhall-lang/tests/import/success/unit/AlternativeWithWrongVariable1A.dhall view
@@ -0,0 +1,1 @@+\(x: Natural) -> x ? y
+ dhall-lang/tests/import/success/unit/AlternativeWithWrongVariable1B.dhall view
@@ -0,0 +1,1 @@+λ(x : Natural) → x
+ dhall-lang/tests/import/success/unit/AlternativeWithWrongVariable2A.dhall view
@@ -0,0 +1,1 @@+\(x: Natural) -> (y + missing) ? x
+ dhall-lang/tests/import/success/unit/AlternativeWithWrongVariable2B.dhall view
@@ -0,0 +1,1 @@+λ(x : Natural) → x
+ dhall-lang/tests/import/success/unit/AsBytesA.dhall view
@@ -0,0 +1,1 @@+../../data/example.bin as Bytes
+ dhall-lang/tests/import/success/unit/AsBytesB.dhall view
@@ -0,0 +1,1 @@+0x"0123456789abcdef"
+ dhall-lang/tests/import/success/unit/DontCacheIfHashA.dhall view
@@ -0,0 +1,5 @@+-- The let triggers a loading of `simple.dhall` in the cache,+-- but the second import uses a hash that corresponds to a different file already in the content-addressed store.+-- This test ensures that we retrieve the value corresponding to the hash and not the path even if the path is in cache.+let x = ../../data/simple.dhall+in ../../data/simple.dhall sha256:3871180b87ecaba8b53fffb2a8b52d3fce98098fab09a6f759358b9e8042eedc
+ dhall-lang/tests/import/success/unit/DontCacheIfHashB.dhall view
@@ -0,0 +1,1 @@+let x = 3 in λ(_ : Type) → λ(_ : Optional _) → merge { `None` = True, `Some` = λ(_ : _@1) → False } _
+ dhall-lang/tests/import/success/unit/ImportRelativeToHomeA.dhall view
@@ -0,0 +1,1 @@+~/hello.dhall ++ " world"
+ dhall-lang/tests/import/success/unit/ImportRelativeToHomeB.dhall view
@@ -0,0 +1,1 @@+"hello" ++ " world"
+ dhall-lang/tests/import/success/unit/MixImportModesA.dhall view
@@ -0,0 +1,2 @@+-- This is to ensure caching doesn't accidentally confuse import modes+{ n = ../../data/simple.dhall, txt = ../../data/simple.dhall as Text, loc = ../../data/simple.dhall as Location }
+ dhall-lang/tests/import/success/unit/MixImportModesB.dhall view
@@ -0,0 +1,1 @@+{ loc = < Environment: Text | Local: Text | Missing | Remote: Text >.Local "./dhall-lang/tests/import/data/simple.dhall", n = 3, txt = "3\n" }
+ dhall-lang/tests/import/success/unit/RecoverTransitiveFailureA.dhall view
@@ -0,0 +1,1 @@+../../failure/unit/FileMissing.dhall ? 0
+ dhall-lang/tests/import/success/unit/RecoverTransitiveFailureB.dhall view
@@ -0,0 +1,1 @@+0
+ dhall-lang/tests/import/success/unit/cors/AllowedAllA.dhall view
@@ -0,0 +1,1 @@+https://raw.githubusercontent.com/dhall-lang/dhall-lang/5ff7ecd2411894dd9ce307dc23020987361d2d43/tests/import/data/cors/AllowedAll.dhall
+ dhall-lang/tests/import/success/unit/cors/AllowedAllB.dhall view
@@ -0,0 +1,1 @@+42
+ dhall-lang/tests/import/success/unit/cors/NoCORSFromLocalA.dhall view
@@ -0,0 +1,1 @@+https://test.dhall-lang.org/cors/NoCORS.dhall
+ dhall-lang/tests/import/success/unit/cors/NoCORSFromLocalB.dhall view
@@ -0,0 +1,1 @@+42
+ dhall-lang/tests/import/success/unit/cors/OnlyGithubA.dhall view
@@ -0,0 +1,1 @@+https://raw.githubusercontent.com/dhall-lang/dhall-lang/5ff7ecd2411894dd9ce307dc23020987361d2d43/tests/import/data/cors/OnlyGithub.dhall
+ dhall-lang/tests/import/success/unit/cors/OnlyGithubB.dhall view
@@ -0,0 +1,1 @@+42
+ dhall-lang/tests/import/success/unit/cors/PreludeA.dhall view
@@ -0,0 +1,1 @@+https://raw.githubusercontent.com/dhall-lang/dhall-lang/acee30866a179c9e9bb3fc02ec8be2883685eb14/tests/import/data/cors/Prelude.dhall
+ dhall-lang/tests/import/success/unit/cors/PreludeB.dhall view
@@ -0,0 +1,1 @@+List/length
+ dhall-lang/tests/import/success/unit/cors/SelfImportAbsolute2A.dhall view
@@ -0,0 +1,1 @@+https://test.dhall-lang.org/cors/SelfImportAbsolute.dhall
+ dhall-lang/tests/import/success/unit/cors/SelfImportAbsolute2B.dhall view
@@ -0,0 +1,1 @@+42
+ dhall-lang/tests/import/success/unit/cors/SelfImportAbsoluteA.dhall view
@@ -0,0 +1,1 @@+https://raw.githubusercontent.com/dhall-lang/dhall-lang/5ff7ecd2411894dd9ce307dc23020987361d2d43/tests/import/data/cors/SelfImportAbsolute.dhall
+ dhall-lang/tests/import/success/unit/cors/SelfImportAbsoluteB.dhall view
@@ -0,0 +1,1 @@+42
+ dhall-lang/tests/import/success/unit/cors/SelfImportRelative2A.dhall view
@@ -0,0 +1,1 @@+https://test.dhall-lang.org/cors/SelfImportRelative.dhall
+ dhall-lang/tests/import/success/unit/cors/SelfImportRelative2B.dhall view
@@ -0,0 +1,1 @@+42
+ dhall-lang/tests/import/success/unit/cors/SelfImportRelativeA.dhall view
@@ -0,0 +1,1 @@+https://raw.githubusercontent.com/dhall-lang/dhall-lang/5ff7ecd2411894dd9ce307dc23020987361d2d43/tests/import/data/cors/SelfImportRelative.dhall
+ dhall-lang/tests/import/success/unit/cors/SelfImportRelativeB.dhall view
@@ -0,0 +1,1 @@+42
+ dhall-lang/tests/import/success/unit/cors/TwoHopsA.dhall view
@@ -0,0 +1,1 @@+https://test.dhall-lang.org/cors/TwoHopsSuccess.dhall
+ dhall-lang/tests/import/success/unit/cors/TwoHopsB.dhall view
@@ -0,0 +1,1 @@+42
+ dhall-lang/tests/normalization/success/regression/ComplexRecordSimplificationA.dhall view
@@ -0,0 +1,1 @@+\(foo: { x: Bool, y: Bool }) -> \(bar: { x: Bool }) -> (foo.{x, y} // bar).{ x }
+ dhall-lang/tests/normalization/success/regression/ComplexRecordSimplificationB.dhall view
@@ -0,0 +1,3 @@+λ(foo : { x : Bool, y : Bool }) →+λ(bar : { x : Bool }) →+  (foo.{ x, y } ⫽ bar).{ x }
+ dhall-lang/tests/normalization/success/regression/ToMapQuotedFieldsA.dhall view
@@ -0,0 +1,1 @@+toMap { `if` = 0, `foo%bar` = 1 }
+ dhall-lang/tests/normalization/success/regression/ToMapQuotedFieldsB.dhall view
@@ -0,0 +1,1 @@+[ { mapKey = "foo%bar", mapValue = 1 }, { mapKey = "if", mapValue = 0 } ]
dhall-lang/tests/normalization/success/remoteSystemsA.dhall view
@@ -1,6 +1,6 @@-let Text/concatMap = ../../../Prelude/Text/concatMap+let Text/concatMap = ../../../Prelude/Text/concatMap.dhall -let Text/concatSep = ../../../Prelude/Text/concatSep+let Text/concatSep = ../../../Prelude/Text/concatSep.dhall  let Row =       { cores :
+ dhall-lang/tests/normalization/success/unit/BytesA.dhall view
@@ -0,0 +1,1 @@+Bytes
+ dhall-lang/tests/normalization/success/unit/BytesB.dhall view
@@ -0,0 +1,1 @@+Bytes
+ dhall-lang/tests/normalization/success/unit/BytesLiteralA.dhall view
@@ -0,0 +1,23 @@+[ 0x"00"+, 0x"01"+, 0x"02"+, 0x"03"+, 0x"04"+, 0x"05"+, 0x"06"+, 0x"07"+, 0x"08"+, 0x"09"+, 0x"0a"+, 0x"0b"+, 0x"0c"+, 0x"0d"+, 0x"0e"+, 0x"0f"+, 0x"0A"+, 0x"0B"+, 0x"0C"+, 0x"0D"+, 0x"0E"+, 0x"0F"+]
+ dhall-lang/tests/normalization/success/unit/BytesLiteralB.dhall view
@@ -0,0 +1,23 @@+[ 0x"00"+, 0x"01"+, 0x"02"+, 0x"03"+, 0x"04"+, 0x"05"+, 0x"06"+, 0x"07"+, 0x"08"+, 0x"09"+, 0x"0a"+, 0x"0b"+, 0x"0c"+, 0x"0d"+, 0x"0e"+, 0x"0f"+, 0x"0A"+, 0x"0B"+, 0x"0C"+, 0x"0D"+, 0x"0E"+, 0x"0F"+]
+ dhall-lang/tests/normalization/success/unit/RecordSortFieldsA.dhall view
@@ -0,0 +1,1 @@+{ b = 1, a = 0 }
+ dhall-lang/tests/normalization/success/unit/RecordSortFieldsB.dhall view
@@ -0,0 +1,1 @@+{ a = 0, b = 1 }
+ dhall-lang/tests/normalization/success/unit/RecordTypeSortFieldsA.dhall view
@@ -0,0 +1,1 @@+{ b : Bool, a : Natural }
+ dhall-lang/tests/normalization/success/unit/RecordTypeSortFieldsB.dhall view
@@ -0,0 +1,1 @@+{ a : Natural, b : Bool }
+ dhall-lang/tests/normalization/success/unit/ShowConstructorEmptyA.dhall view
@@ -0,0 +1,1 @@+showConstructor <A>.A
+ dhall-lang/tests/normalization/success/unit/ShowConstructorEmptyB.dhall view
@@ -0,0 +1,1 @@+"A"
+ dhall-lang/tests/normalization/success/unit/ShowConstructorNonEmptyA.dhall view
@@ -0,0 +1,1 @@+showConstructor (< A : Bool>.A False)
+ dhall-lang/tests/normalization/success/unit/ShowConstructorNonEmptyB.dhall view
@@ -0,0 +1,1 @@+"A"
dhall-lang/tests/normalization/success/unit/TextReplaceAbstractA.dhall view
@@ -1,4 +1,3 @@-{- This test verifies that an implementation correctly permits both the-   "replacement" and the "haystack" to be abstract.+{- This test verifies that an implementation works with an abstract "replacement". -}-λ(x : Text) → λ(y : Text) → Text/replace "a" "-${x}-" "_a_${y}_a_"+λ(x : Text) → Text/replace "a" "-${x}-" "_a__a_"
dhall-lang/tests/normalization/success/unit/TextReplaceAbstractB.dhall view
@@ -1,1 +1,1 @@-λ(x : Text) → λ(y : Text) → "_-${x}-_${y}_-${x}-_"+λ(x : Text) → "_-${x}-__-${x}-_"
+ dhall-lang/tests/normalization/success/unit/TextReplaceAbstractHaystackA.dhall view
@@ -0,0 +1,4 @@+{- This test verifies that an implementation does not beta normalize with an+   abstract "haystack".+-}+λ(x : Text) → λ(y : Text) → Text/replace "a" "-${x}-" "_a_${y}_a_"
+ dhall-lang/tests/normalization/success/unit/TextReplaceAbstractHaystackB.dhall view
@@ -0,0 +1,1 @@+λ(x : Text) → λ(y : Text) → Text/replace "a" "-${x}-" "_a_${y}_a_"
+ dhall-lang/tests/normalization/success/unit/TextReplaceEmpty1A.dhall view
@@ -0,0 +1,1 @@+Text/replace ""
+ dhall-lang/tests/normalization/success/unit/TextReplaceEmpty1B.dhall view
@@ -0,0 +1,1 @@+Text/replace ""
+ dhall-lang/tests/normalization/success/unit/TextReplaceEmpty2A.dhall view
@@ -0,0 +1,2 @@+λ(replacement : Text) →+  Text/replace "" replacement
+ dhall-lang/tests/normalization/success/unit/TextReplaceEmpty2B.dhall view
@@ -0,0 +1,2 @@+λ(replacement : Text) →+  Text/replace "" replacement
+ dhall-lang/tests/normalization/success/unit/TextReplaceEmpty3A.dhall view
@@ -0,0 +1,3 @@+λ(replacement : Text) →+λ(haystack : Text) →+  Text/replace "" replacement haystack
+ dhall-lang/tests/normalization/success/unit/TextReplaceEmpty3B.dhall view
@@ -0,0 +1,1 @@+λ(replacement : Text) → λ(haystack : Text) → haystack
− dhall-lang/tests/normalization/success/unit/TextReplaceEmptyA.dhall
@@ -1,1 +0,0 @@-Text/replace "" "bar" "foo"
− dhall-lang/tests/normalization/success/unit/TextReplaceEmptyB.dhall
@@ -1,1 +0,0 @@-"foo"
+ dhall-lang/tests/normalization/success/unit/TextReplaceOverlappingA.dhall view
@@ -0,0 +1,1 @@+Text/replace "aa" "b" "aaaaa"
+ dhall-lang/tests/normalization/success/unit/TextReplaceOverlappingB.dhall view
@@ -0,0 +1,1 @@+"bba"
+ dhall-lang/tests/normalization/success/unit/TextReplaceVarA.dhall view
@@ -0,0 +1,3 @@+{- This test verifies that an implementation works with a variable as "replacement".+-}+λ(x : Text) → Text/replace "a" x "aaa"
+ dhall-lang/tests/normalization/success/unit/TextReplaceVarB.dhall view
@@ -0,0 +1,1 @@+λ(x : Text) → "${x}${x}${x}"
+ dhall-lang/tests/normalization/success/unit/TimeAsRecordA.dhall view
@@ -0,0 +1,2 @@+-- Timestamps are records, and this is a no-op+2000-01-01T12:00:00+08:00.{ time, date, timeZone }
+ dhall-lang/tests/normalization/success/unit/TimeAsRecordB.dhall view
@@ -0,0 +1,1 @@+2000-01-01T12:00:00+08:00
+ dhall-lang/tests/normalization/success/unit/WithOnOptionalNoneA.dhall view
@@ -0,0 +1,1 @@+(None Natural) with ? = 1
+ dhall-lang/tests/normalization/success/unit/WithOnOptionalNoneB.dhall view
@@ -0,0 +1,1 @@+None Natural
+ dhall-lang/tests/normalization/success/unit/WithOnOptionalSomeA.dhall view
@@ -0,0 +1,1 @@+(Some 0) with ? = 1
+ dhall-lang/tests/normalization/success/unit/WithOnOptionalSomeB.dhall view
@@ -0,0 +1,1 @@+Some 1
+ dhall-lang/tests/normalization/success/unit/WithOptionalDeeplyNestedA.dhall view
@@ -0,0 +1,1 @@+(Some { x = Some { y = Some { z = Some 0 } } }) with ?.x.?.y.?.z.? = 1
+ dhall-lang/tests/normalization/success/unit/WithOptionalDeeplyNestedB.dhall view
@@ -0,0 +1,1 @@+Some { x = Some { y = Some { z = Some 1 } } }
+ dhall-lang/tests/normalization/success/unit/WithOptionalNestedA.dhall view
@@ -0,0 +1,1 @@+{ x = Some 0 } with x.? = 1
+ dhall-lang/tests/normalization/success/unit/WithOptionalNestedB.dhall view
@@ -0,0 +1,1 @@+{ x = Some 1 }
dhall-lang/tests/parser/failure/boundBuiltins.dhall view
@@ -1,6 +1,6 @@ {-     Builtin names are disallowed in bound variables.-    The grammar doesn't explicitely disallow this, but the implementation should+    The grammar doesn't explicitly disallow this, but the implementation should     refuse it. See the comments above the `nonreserved-label` rule. -} let Bool : Natural = 1 in Bool
+ dhall-lang/tests/parser/failure/bytesInvalid.dhall view
@@ -0,0 +1,1 @@+0x"invalid"
+ dhall-lang/tests/parser/failure/bytesOddLength.dhall view
@@ -0,0 +1,1 @@+0x"0"
+ dhall-lang/tests/parser/failure/spacing/LetNoSpace3.dhall view
@@ -0,0 +1,1 @@+let x = NaNin x
+ dhall-lang/tests/parser/failure/spacing/LetNoSpace4.dhall view
@@ -0,0 +1,1 @@+let x = 3let y = x in y
+ dhall-lang/tests/parser/failure/time/DateTimeZone.dhall view
@@ -0,0 +1,2 @@+-- A date and time zone is not valid (because the time is missing)+2011-04-01+02:00
+ dhall-lang/tests/parser/failure/time/InvalidDayOfMonth.dhall view
@@ -0,0 +1,2 @@+-- April only has 30 days+2000-04-31
+ dhall-lang/tests/parser/failure/time/InvalidHour.dhall view
@@ -0,0 +1,2 @@+-- Hours must range between 0-23+24:00:00
+ dhall-lang/tests/parser/failure/time/InvalidLeapSecond.dhall view
@@ -0,0 +1,3 @@+-- Leap seconds are not permitted by the Dhall standard, even though RFC 3339+-- supports them+2016-12-31T23:59:60
+ dhall-lang/tests/parser/failure/time/InvalidMinute.dhall view
@@ -0,0 +1,2 @@+-- Minutes must range between 0-59+00:60:00
+ dhall-lang/tests/parser/failure/time/InvalidMonth.dhall view
@@ -0,0 +1,2 @@+-- Months must be between 1-12+2000-13-01
+ dhall-lang/tests/parser/failure/time/InvalidSecond.dhall view
@@ -0,0 +1,2 @@+-- Seconds must range between 0-59 (and leap seconds are not supported)+00:00:60
+ dhall-lang/tests/parser/failure/time/NegativeYear.dhall view
@@ -0,0 +1,2 @@+-- Negative years are not permitted+-0001-01-01
+ dhall-lang/tests/parser/failure/time/YearTooLarge.dhall view
@@ -0,0 +1,2 @@+-- Only 4-digit years are permitted+10000-01-01
+ dhall-lang/tests/parser/failure/unit/WithWhitespace.dhall view
@@ -0,0 +1,2 @@+-- For https://github.com/dhall-lang/dhall-haskell/issues/2212+{=}with foo = 0with bar = 1
+ dhall-lang/tests/parser/failure/unit/showConstructorAlone.dhall view
@@ -0,0 +1,1 @@+showConstructor
+ dhall-lang/tests/parser/success/binaryA.dhall view
@@ -0,0 +1,8 @@+  λ(x : Bool)+→ λ(x : Bool)+→ { example0 = 0b0+  , example1 = 0b10+  , example2 = -0b11001+  , example3 = +0b100+  , example4 = x@0b01+  }
+ dhall-lang/tests/parser/success/binaryB.dhallb view

binary file changed (absent → 83 bytes)

dhall-lang/tests/parser/success/builtinsA.dhall view
@@ -1,36 +1,40 @@-[ Natural/fold-, Natural/build-, Natural/isZero-, Natural/even-, Natural/odd-, Natural/toInteger-, Natural/show-, Integer/toDouble-, Integer/show-, Integer/negate-, Integer/clamp-, Natural/subtract+[ Date/show , Double/show+, Integer/clamp+, Integer/negate+, Integer/show+, Integer/toDouble , List/build , List/fold-, List/length , List/head-, List/last , List/indexed+, List/last+, List/length , List/reverse-, Text/show+, Natural/build+, Natural/even+, Natural/fold+, Natural/isZero+, Natural/odd+, Natural/show+, Natural/subtract+, Natural/toInteger , Text/replace+, Text/show+, Time/show+, TimeZone/show , Bool-, True+, Bytes+, Date+, Double , False-, Optional-, None-, Natural , Integer-, Double-, Text , List-, Type-, Kind-, Sort+, Natural+, None+, Optional+, Text+, Time+, TimeZone+, True ]
dhall-lang/tests/parser/success/builtinsB.dhallb view
@@ -1,1 +1,1 @@-˜%ölNatural/foldmNatural/buildnNatural/isZerolNatural/evenkNatural/oddqNatural/toIntegerlNatural/showpInteger/toDoublelInteger/shownInteger/negatemInteger/clamppNatural/subtractkDouble/showjList/buildiList/foldkList/lengthiList/headiList/lastlList/indexedlList/reverseiText/showlText/replacedBoolõôhOptionaldNonegNaturalgIntegerfDoubledTextdListdTypedKinddSort+˜)öiDate/showkDouble/showmInteger/clampnInteger/negatelInteger/showpInteger/toDoublejList/buildiList/foldiList/headlList/indexediList/lastkList/lengthlList/reversemNatural/buildlNatural/evenlNatural/foldnNatural/isZerokNatural/oddlNatural/showpNatural/subtractqNatural/toIntegerlText/replaceiText/showiTime/showmTimeZone/showdBooleBytesdDatefDoubleôgIntegerdListgNaturaldNonehOptionaldTextdTimehTimeZoneõ
+ dhall-lang/tests/parser/success/bytesA.dhall view
@@ -0,0 +1,25 @@+[ 0x""+, 0x"00"+, 0x"01"+, 0x"02"+, 0x"03"+, 0x"04"+, 0x"05"+, 0x"06"+, 0x"07"+, 0x"08"+, 0x"09"+, 0x"0a"+, 0x"0b"+, 0x"0c"+, 0x"0d"+, 0x"0e"+, 0x"0f"+, 0x"0A"+, 0x"0B"+, 0x"0C"+, 0x"0D"+, 0x"0E"+, 0x"0F"+, 0x"000102030405060708090a0b0c0d0e0f0A0B0C0D0E0F"+]
+ dhall-lang/tests/parser/success/bytesB.dhallb view

binary file changed (absent → 144 bytes)

+ dhall-lang/tests/parser/success/listWithCommentA.dhall view
@@ -0,0 +1,3 @@+[+  1, -- item one+{- foo -} 2, 3 ]
+ dhall-lang/tests/parser/success/listWithCommentB.dhallb view
@@ -0,0 +1,1 @@+…ö‚‚‚
+ dhall-lang/tests/parser/success/mixedBlockLineCommentA.dhall view
@@ -0,0 +1,6 @@+{- foo -}+-- bar+{- --baz -}+-- {- qux -}++1
+ dhall-lang/tests/parser/success/mixedBlockLineCommentB.dhallb view
@@ -0,0 +1,1 @@
+ dhall-lang/tests/parser/success/text/multilinePreserveCommentA.dhall view
@@ -0,0 +1,8 @@+{- A comment within the interior of a multi-line literal counts as part of the+   literal+-}++''+-- Hello+{- world -}+''
+ dhall-lang/tests/parser/success/text/multilinePreserveCommentB.dhallb view
@@ -0,0 +1,2 @@+‚u-- Hello+{- world -}
dhall-lang/tests/parser/success/text/preserveCommentA.dhall view
@@ -1,8 +1,1 @@-{- A comment within the interior of a multi-line literal counts as part of the-   literal--}--''--- Hello-{- world -}-''+"-- $--$--{--}$"
dhall-lang/tests/parser/success/text/preserveCommentB.dhallb view
@@ -1,2 +1,1 @@-‚u-- Hello-{- world -}+‚n-- $--$--{--}$
+ dhall-lang/tests/parser/success/text/unicodeBracedA.dhall view
@@ -0,0 +1,1 @@+"\u{1}\u{10}\u{100}\u{1000}\u{10000}\u{100000}"
+ dhall-lang/tests/parser/success/text/unicodeBracedB.dhallb view
@@ -0,0 +1,1 @@+‚oĀက𐀀ô€€€
+ dhall-lang/tests/parser/success/text/unicodeEscapedA.dhall view
@@ -0,0 +1,1 @@+"A\u2115B\u{1FA00}C\u{43}D\u{00000001F574}E\u0022F"
+ dhall-lang/tests/parser/success/text/unicodeEscapedB.dhallb view
@@ -0,0 +1,1 @@+‚sAℕB🨀CCD🕴E"F
+ dhall-lang/tests/parser/success/text/unicodePlane16A.dhall view
@@ -0,0 +1,1 @@+"\u{10fffd}\u{1fffd}"
+ dhall-lang/tests/parser/success/text/unicodePlane16B.dhallb view
@@ -0,0 +1,1 @@+‚hô¿½ðŸ¿½
+ dhall-lang/tests/parser/success/time/DateTimeA.dhall view
@@ -0,0 +1,1 @@+1960-12-25T04:23:34
+ dhall-lang/tests/parser/success/time/DateTimeB.dhallb view

binary file changed (absent → 32 bytes)

+ dhall-lang/tests/parser/success/time/DateTimeTimeZoneA.dhall view
@@ -0,0 +1,1 @@+2020-01-01T12:00:00-08:00
+ dhall-lang/tests/parser/success/time/DateTimeTimeZoneB.dhallb view

binary file changed (absent → 45 bytes)

+ dhall-lang/tests/parser/success/time/LowercaseTA.dhall view
@@ -0,0 +1,2 @@+-- Check that lowercase `t` is supported+2000-01-01t12:00:00
+ dhall-lang/tests/parser/success/time/LowercaseTB.dhallb view

binary file changed (absent → 30 bytes)

+ dhall-lang/tests/parser/success/time/TimeTimeZoneA.dhall view
@@ -0,0 +1,1 @@+00:00:00+00:00
+ dhall-lang/tests/parser/success/time/TimeTimeZoneB.dhallb view

binary file changed (absent → 32 bytes)

+ dhall-lang/tests/parser/success/time/TimeTimeZoneZA.dhall view
@@ -0,0 +1,5 @@+-- Same as `./TimeTimeZoneA.dhall`, but with `Z` as the `TimeZone`+--+-- This ensures that implementation still parse `Z` in conjunction with a time,+-- even if `Z` by itself is not permitted+00:00:00Z
+ dhall-lang/tests/parser/success/time/TimeTimeZoneZB.dhallb view

binary file changed (absent → 32 bytes)

+ dhall-lang/tests/parser/success/unit/DateA.dhall view
@@ -0,0 +1,1 @@+Date
+ dhall-lang/tests/parser/success/unit/DateB.dhallb view
@@ -0,0 +1,1 @@+dDate
+ dhall-lang/tests/parser/success/unit/DateLiteralA.dhall view
@@ -0,0 +1,1 @@+2020-01-01
+ dhall-lang/tests/parser/success/unit/DateLiteralB.dhallb view
@@ -0,0 +1,1 @@+„ä
+ dhall-lang/tests/parser/success/unit/DeBruijnIndexA.dhall view
@@ -0,0 +1,1 @@+x == x@0
+ dhall-lang/tests/parser/success/unit/DeBruijnIndexB.dhallb view

binary file changed (absent → 11 bytes)

− dhall-lang/tests/parser/success/unit/DoubleLitSecretelyIntA.dhall
@@ -1,5 +0,0 @@-{--    Some languages do not make principled distinctions between number types, so-    this checks that this Double is not silently considered as a Natural--}-1.0
− dhall-lang/tests/parser/success/unit/DoubleLitSecretelyIntB.dhallb

binary file changed (3 → absent bytes)

+ dhall-lang/tests/parser/success/unit/DoubleLitSecretlyIntA.dhall view
@@ -0,0 +1,5 @@+{-+    Some languages do not make principled distinctions between number types, so+    this checks that this Double is not silently considered as a Natural+-}+1.0
+ dhall-lang/tests/parser/success/unit/DoubleLitSecretlyIntB.dhallb view

binary file changed (absent → 3 bytes)

+ dhall-lang/tests/parser/success/unit/ForallUnicodeA.dhall view
@@ -0,0 +1,1 @@+∀(x : T) -> y
+ dhall-lang/tests/parser/success/unit/ForallUnicodeB.dhallb view

binary file changed (absent → 12 bytes)

+ dhall-lang/tests/parser/success/unit/ListWithNewlineA.dhall view
@@ -0,0 +1,11 @@+[ [+    1,+    2,+    3,+  ]+, [+  , 1+  , 2+  , 3+  ]+]
+ dhall-lang/tests/parser/success/unit/ListWithNewlineB.dhallb view
@@ -0,0 +1,1 @@+„ö…ö‚‚‚…ö‚‚‚
− dhall-lang/tests/parser/success/unit/RecordFieldAccessA.dhall
@@ -1,1 +0,0 @@-r.x
− dhall-lang/tests/parser/success/unit/RecordFieldAccessB.dhallb

binary file changed (8 → absent bytes)

+ dhall-lang/tests/parser/success/unit/RecordLitEmptyBothCommasA.dhall view
@@ -0,0 +1,1 @@+{ , =, }
+ dhall-lang/tests/parser/success/unit/RecordLitEmptyBothCommasB.dhallb view
@@ -0,0 +1,1 @@+‚ 
− dhall-lang/tests/parser/success/unit/RecordProjectFieldsA.dhall
@@ -1,1 +0,0 @@-r.{ x, y, z }
− dhall-lang/tests/parser/success/unit/RecordProjectFieldsB.dhallb

binary file changed (12 → absent bytes)

+ dhall-lang/tests/parser/success/unit/RecordTypeEmptyA.dhall view
@@ -0,0 +1,1 @@+{}
+ dhall-lang/tests/parser/success/unit/RecordTypeEmptyB.dhallb view
@@ -0,0 +1,1 @@+‚ 
+ dhall-lang/tests/parser/success/unit/ShebangA.dhall view
@@ -0,0 +1,2 @@+#!/usr/bin/env -S dhall text --file+"A"
+ dhall-lang/tests/parser/success/unit/ShebangB.dhallb view
@@ -0,0 +1,1 @@+‚aA
+ dhall-lang/tests/parser/success/unit/ShebangNixA.dhall view
@@ -0,0 +1,3 @@+#! /usr/bin/env nix-shell+#! nix-shell -i "dhall --file" -p dhall+42
+ dhall-lang/tests/parser/success/unit/ShebangNixB.dhallb view
@@ -0,0 +1,1 @@+‚*
+ dhall-lang/tests/parser/success/unit/ShowConstructorA.dhall view
@@ -0,0 +1,1 @@+showConstructor <A>.A
+ dhall-lang/tests/parser/success/unit/ShowConstructorB.dhallb view
@@ -0,0 +1,1 @@+‚"ƒ	‚¡aAöaA
+ dhall-lang/tests/parser/success/unit/ShowConstructorWithValueA.dhall view
@@ -0,0 +1,1 @@+showConstructor (<A : Bool>.A False)
+ dhall-lang/tests/parser/success/unit/ShowConstructorWithValueB.dhallb view

binary file changed (absent → 20 bytes)

+ dhall-lang/tests/parser/success/unit/TimeA.dhall view
@@ -0,0 +1,1 @@+Time
+ dhall-lang/tests/parser/success/unit/TimeB.dhallb view
@@ -0,0 +1,1 @@+dTime
+ dhall-lang/tests/parser/success/unit/TimeLiteralA.dhall view
@@ -0,0 +1,1 @@+12:00:00
+ dhall-lang/tests/parser/success/unit/TimeLiteralB.dhallb view

binary file changed (absent → 9 bytes)

+ dhall-lang/tests/parser/success/unit/TimeZoneA.dhall view
@@ -0,0 +1,1 @@+TimeZone
+ dhall-lang/tests/parser/success/unit/TimeZoneB.dhallb view
@@ -0,0 +1,1 @@+hTimeZone
+ dhall-lang/tests/parser/success/unit/TimeZoneLiteralA.dhall view
@@ -0,0 +1,1 @@++08:00
+ dhall-lang/tests/parser/success/unit/TimeZoneLiteralB.dhallb view

binary file changed (absent → 6 bytes)

+ dhall-lang/tests/parser/success/unit/TrailingLineCommentWithoutNewlineA.dhall view
@@ -0,0 +1,2 @@+-- This test verifies that a trailing line comment does not require a newline+1--
+ dhall-lang/tests/parser/success/unit/TrailingLineCommentWithoutNewlineB.dhallb view
@@ -0,0 +1,1 @@
+ dhall-lang/tests/parser/success/unit/WithSomeA.dhall view
@@ -0,0 +1,1 @@+{ Some = 0 } with Some = 1
+ dhall-lang/tests/parser/success/unit/WithSomeB.dhallb view

binary file changed (absent → 23 bytes)

+ dhall-lang/tests/parser/success/unit/operators/EquivalenceAssocA.dhall view
@@ -0,0 +1,1 @@+w === x === y === z
+ dhall-lang/tests/parser/success/unit/operators/EquivalenceAssocB.dhallb view

binary file changed (absent → 25 bytes)

dhall-lang/tests/parser/success/unit/operators/RecursiveRecordMergeA.dhall view
@@ -1,1 +1,1 @@-x //\\ y+x /\ y
dhall-lang/tests/parser/success/unit/operators/RecursiveRecordMergeAssocA.dhall view
@@ -1,1 +1,1 @@-w //\\ x //\\ y //\\ z+w /\ x /\ y /\ z
dhall-lang/tests/parser/success/unit/operators/RecursiveRecordMergeAssocB.dhallb view

binary file changed (25 → 25 bytes)

dhall-lang/tests/parser/success/unit/operators/RecursiveRecordMergeB.dhallb view

binary file changed (11 → 11 bytes)

dhall-lang/tests/parser/success/unit/operators/RecursiveRecordTypeMergeA.dhall view
@@ -1,1 +1,1 @@-x /\ y+x //\\ y
dhall-lang/tests/parser/success/unit/operators/RecursiveRecordTypeMergeAssocA.dhall view
@@ -1,1 +1,1 @@-w /\ x /\ y /\ z+w //\\ x //\\ y //\\ z
dhall-lang/tests/parser/success/unit/operators/RecursiveRecordTypeMergeAssocB.dhallb view

binary file changed (25 → 25 bytes)

dhall-lang/tests/parser/success/unit/operators/RecursiveRecordTypeMergeB.dhallb view

binary file changed (11 → 11 bytes)

+ dhall-lang/tests/parser/success/withQuestionMarkA.dhall view
@@ -0,0 +1,1 @@+(Some 0) with ? = 1
+ dhall-lang/tests/parser/success/withQuestionMarkB.dhallb view

binary file changed (absent → 14 bytes)

dhall-lang/tests/semantic-hash/success/prelude/Bool/and/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/and [ True, False, True ]+../../../../../../Prelude/Bool/and.dhall [ True, False, True ]
dhall-lang/tests/semantic-hash/success/prelude/Bool/and/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/and ([] : List Bool)+../../../../../../Prelude/Bool/and.dhall ([] : List Bool)
dhall-lang/tests/semantic-hash/success/prelude/Bool/build/0A.dhall view
@@ -1,2 +1,2 @@-../../../../../../Prelude/Bool/build +../../../../../../Prelude/Bool/build.dhall (λ(bool : Type) → λ(true : bool) → λ(false : bool) → true)
dhall-lang/tests/semantic-hash/success/prelude/Bool/build/1A.dhall view
@@ -1,2 +1,2 @@-../../../../../../Prelude/Bool/build +../../../../../../Prelude/Bool/build.dhall (λ(bool : Type) → λ(true : bool) → λ(false : bool) → false)
dhall-lang/tests/semantic-hash/success/prelude/Bool/even/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/even [ False, True, False ]+../../../../../../Prelude/Bool/even.dhall [ False, True, False ]
dhall-lang/tests/semantic-hash/success/prelude/Bool/even/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/even [ False, True ]+../../../../../../Prelude/Bool/even.dhall [ False, True ]
dhall-lang/tests/semantic-hash/success/prelude/Bool/even/2A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/even [ False ]+../../../../../../Prelude/Bool/even.dhall [ False ]
dhall-lang/tests/semantic-hash/success/prelude/Bool/even/3A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/even ([] : List Bool)+../../../../../../Prelude/Bool/even.dhall ([] : List Bool)
dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/fold True Natural 0 1+../../../../../../Prelude/Bool/fold.dhall True Natural 0 1
dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/fold False Natural 0 1+../../../../../../Prelude/Bool/fold.dhall False Natural 0 1
dhall-lang/tests/semantic-hash/success/prelude/Bool/not/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/not True+../../../../../../Prelude/Bool/not.dhall True
dhall-lang/tests/semantic-hash/success/prelude/Bool/not/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/not False+../../../../../../Prelude/Bool/not.dhall False
dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/odd [ True, False, True ]+../../../../../../Prelude/Bool/odd.dhall [ True, False, True ]
dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/odd [ True, False ]+../../../../../../Prelude/Bool/odd.dhall [ True, False ]
dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/2A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/odd [ True ]+../../../../../../Prelude/Bool/odd.dhall [ True ]
dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/3A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/odd ([] : List Bool)+../../../../../../Prelude/Bool/odd.dhall ([] : List Bool)
dhall-lang/tests/semantic-hash/success/prelude/Bool/or/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/or [ True, False, True ]+../../../../../../Prelude/Bool/or.dhall [ True, False, True ]
dhall-lang/tests/semantic-hash/success/prelude/Bool/or/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/or ([] : List Bool)+../../../../../../Prelude/Bool/or.dhall ([] : List Bool)
dhall-lang/tests/semantic-hash/success/prelude/Bool/show/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/show True+../../../../../../Prelude/Bool/show.dhall True
dhall-lang/tests/semantic-hash/success/prelude/Bool/show/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/show False+../../../../../../Prelude/Bool/show.dhall False
dhall-lang/tests/semantic-hash/success/prelude/Double/show/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Double/show -3.1+../../../../../../Prelude/Double/show.dhall -3.1
dhall-lang/tests/semantic-hash/success/prelude/Double/show/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Double/show 0.4+../../../../../../Prelude/Double/show.dhall 0.4
dhall-lang/tests/semantic-hash/success/prelude/Integer/show/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Integer/show -3+../../../../../../Prelude/Integer/show.dhall -3
dhall-lang/tests/semantic-hash/success/prelude/Integer/show/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Integer/show +0+../../../../../../Prelude/Integer/show.dhall +0
dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Integer/toDouble -3+../../../../../../Prelude/Integer/toDouble.dhall -3
dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Integer/toDouble +2+../../../../../../Prelude/Integer/toDouble.dhall +2
dhall-lang/tests/semantic-hash/success/prelude/List/all/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/all Natural Natural/even [ 2, 3, 5 ]+../../../../../../Prelude/List/all.dhall Natural Natural/even [ 2, 3, 5 ]
dhall-lang/tests/semantic-hash/success/prelude/List/all/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/all Natural Natural/even ([] : List Natural)+../../../../../../Prelude/List/all.dhall Natural Natural/even ([] : List Natural)
dhall-lang/tests/semantic-hash/success/prelude/List/any/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/any Natural Natural/even [ 2, 3, 5 ]+../../../../../../Prelude/List/any.dhall Natural Natural/even [ 2, 3, 5 ]
dhall-lang/tests/semantic-hash/success/prelude/List/any/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/any Natural Natural/even ([] : List Natural)+../../../../../../Prelude/List/any.dhall Natural Natural/even ([] : List Natural)
dhall-lang/tests/semantic-hash/success/prelude/List/build/0A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/List/build+../../../../../../Prelude/List/build.dhall Text ( λ(list : Type) → λ(cons : Text → list → list)
dhall-lang/tests/semantic-hash/success/prelude/List/build/1A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/List/build+../../../../../../Prelude/List/build.dhall Text ( λ(list : Type) → λ(cons : Text → list → list)
dhall-lang/tests/semantic-hash/success/prelude/List/concat/0A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/List/concat Natural+../../../../../../Prelude/List/concat.dhall Natural [ [ 0, 1, 2 ] , [ 3, 4 ] , [ 5, 6, 7, 8 ]
dhall-lang/tests/semantic-hash/success/prelude/List/concat/1A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/List/concat Natural+../../../../../../Prelude/List/concat.dhall Natural [ [] : List Natural , [] : List Natural , [] : List Natural
dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/concatMap Natural Natural (λ(n : Natural) → [ n, n ]) [ 2, 3, 5 ]+../../../../../../Prelude/List/concatMap.dhall Natural Natural (λ(n : Natural) → [ n, n ]) [ 2, 3, 5 ]
dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/concatMap Natural Natural (λ(n : Natural) → [ n, n ]) ([] : List Natural)+../../../../../../Prelude/List/concatMap.dhall Natural Natural (λ(n : Natural) → [ n, n ]) ([] : List Natural)
dhall-lang/tests/semantic-hash/success/prelude/List/filter/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/filter Natural Natural/even [ 2, 3, 5 ]+../../../../../../Prelude/List/filter.dhall Natural Natural/even [ 2, 3, 5 ]
dhall-lang/tests/semantic-hash/success/prelude/List/filter/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/filter Natural Natural/odd [ 2, 3, 5 ]+../../../../../../Prelude/List/filter.dhall Natural Natural/odd [ 2, 3, 5 ]
dhall-lang/tests/semantic-hash/success/prelude/List/fold/0A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/List/fold+../../../../../../Prelude/List/fold.dhall Natural [ 2, 3, 5 ] Natural
dhall-lang/tests/semantic-hash/success/prelude/List/fold/1A.dhall view
@@ -1,5 +1,5 @@   λ(nil : Natural)-→ ../../../../../../Prelude/List/fold+→ ../../../../../../Prelude/List/fold.dhall   Natural   [ 2, 3, 5 ]   Natural
dhall-lang/tests/semantic-hash/success/prelude/List/fold/2A.dhall view
@@ -1,4 +1,4 @@   λ(list : Type) → λ(cons : Natural → list → list) → λ(nil : list)-→ ../../../../../../Prelude/List/fold Natural [ 2, 3, 5 ] list cons nil+→ ../../../../../../Prelude/List/fold.dhall Natural [ 2, 3, 5 ] list cons nil
dhall-lang/tests/semantic-hash/success/prelude/List/generate/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/generate 5 Bool Natural/even+../../../../../../Prelude/List/generate.dhall 5 Bool Natural/even
dhall-lang/tests/semantic-hash/success/prelude/List/generate/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/generate 0 Bool Natural/even+../../../../../../Prelude/List/generate.dhall 0 Bool Natural/even
dhall-lang/tests/semantic-hash/success/prelude/List/head/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/head Natural [ 0, 1, 2 ]+../../../../../../Prelude/List/head.dhall Natural [ 0, 1, 2 ]
dhall-lang/tests/semantic-hash/success/prelude/List/head/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/head Natural ([] : List Natural)+../../../../../../Prelude/List/head.dhall Natural ([] : List Natural)
dhall-lang/tests/semantic-hash/success/prelude/List/indexed/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/indexed Bool [ True, False, True ]+../../../../../../Prelude/List/indexed.dhall Bool [ True, False, True ]
dhall-lang/tests/semantic-hash/success/prelude/List/indexed/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/indexed Bool ([] : List Bool)+../../../../../../Prelude/List/indexed.dhall Bool ([] : List Bool)
dhall-lang/tests/semantic-hash/success/prelude/List/iterate/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/iterate 10 Natural (λ(x : Natural) → x * 2) 1+../../../../../../Prelude/List/iterate.dhall 10 Natural (λ(x : Natural) → x * 2) 1
dhall-lang/tests/semantic-hash/success/prelude/List/iterate/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/iterate 0 Natural (λ(x : Natural) → x * 2) 1+../../../../../../Prelude/List/iterate.dhall 0 Natural (λ(x : Natural) → x * 2) 1
dhall-lang/tests/semantic-hash/success/prelude/List/last/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/last Natural [ 0, 1, 2 ]+../../../../../../Prelude/List/last.dhall Natural [ 0, 1, 2 ]
dhall-lang/tests/semantic-hash/success/prelude/List/last/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/last Natural ([] : List Natural)+../../../../../../Prelude/List/last.dhall Natural ([] : List Natural)
dhall-lang/tests/semantic-hash/success/prelude/List/length/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/length Natural [ 0, 1, 2 ]+../../../../../../Prelude/List/length.dhall Natural [ 0, 1, 2 ]
dhall-lang/tests/semantic-hash/success/prelude/List/length/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/length Natural ([] : List Natural)+../../../../../../Prelude/List/length.dhall Natural ([] : List Natural)
dhall-lang/tests/semantic-hash/success/prelude/List/map/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/map Natural Bool Natural/even [ 2, 3, 5 ]+../../../../../../Prelude/List/map.dhall Natural Bool Natural/even [ 2, 3, 5 ]
dhall-lang/tests/semantic-hash/success/prelude/List/map/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/map Natural Bool Natural/even ([] : List Natural)+../../../../../../Prelude/List/map.dhall Natural Bool Natural/even ([] : List Natural)
dhall-lang/tests/semantic-hash/success/prelude/List/null/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/null Natural [ 0, 1, 2 ]+../../../../../../Prelude/List/null.dhall Natural [ 0, 1, 2 ]
dhall-lang/tests/semantic-hash/success/prelude/List/null/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/null Natural ([] : List Natural)+../../../../../../Prelude/List/null.dhall Natural ([] : List Natural)
dhall-lang/tests/semantic-hash/success/prelude/List/replicate/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/replicate 9 Natural 1+../../../../../../Prelude/List/replicate.dhall 9 Natural 1
dhall-lang/tests/semantic-hash/success/prelude/List/replicate/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/replicate 0 Natural 1+../../../../../../Prelude/List/replicate.dhall 0 Natural 1
dhall-lang/tests/semantic-hash/success/prelude/List/reverse/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/reverse Natural [ 0, 1, 2 ]+../../../../../../Prelude/List/reverse.dhall Natural [ 0, 1, 2 ]
dhall-lang/tests/semantic-hash/success/prelude/List/reverse/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/reverse Natural ([] : List Natural)+../../../../../../Prelude/List/reverse.dhall Natural ([] : List Natural)
dhall-lang/tests/semantic-hash/success/prelude/List/shifted/0A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/List/shifted+../../../../../../Prelude/List/shifted.dhall Bool [ [ { index = 0, value = True }   , { index = 1, value = True }
dhall-lang/tests/semantic-hash/success/prelude/List/shifted/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/shifted Bool ([] : List (List { index : Natural, value : Bool }))+../../../../../../Prelude/List/shifted.dhall Bool ([] : List (List { index : Natural, value : Bool }))
dhall-lang/tests/semantic-hash/success/prelude/List/unzip/0A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/List/unzip+../../../../../../Prelude/List/unzip.dhall Text Bool [ { _1 = "ABC", _2 = True }
dhall-lang/tests/semantic-hash/success/prelude/List/unzip/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/unzip Text Bool ([] : List { _1 : Text, _2 : Bool })+../../../../../../Prelude/List/unzip.dhall Text Bool ([] : List { _1 : Text, _2 : Bool })
dhall-lang/tests/semantic-hash/success/prelude/Natural/build/0A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/Natural/build+../../../../../../Prelude/Natural/build.dhall ( λ(natural : Type) → λ(succ : natural → natural) → λ(zero : natural)
dhall-lang/tests/semantic-hash/success/prelude/Natural/build/1A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/Natural/build+../../../../../../Prelude/Natural/build.dhall ( λ(natural : Type) → λ(succ : natural → natural) → λ(zero : natural)
dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/enumerate 10+../../../../../../Prelude/Natural/enumerate.dhall 10
dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/enumerate 0+../../../../../../Prelude/Natural/enumerate.dhall 0
dhall-lang/tests/semantic-hash/success/prelude/Natural/even/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/even 3+../../../../../../Prelude/Natural/even.dhall 3
dhall-lang/tests/semantic-hash/success/prelude/Natural/even/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/even 0+../../../../../../Prelude/Natural/even.dhall 0
dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/fold 3 Natural (λ(x : Natural) → 5 * x) 1+../../../../../../Prelude/Natural/fold.dhall 3 Natural (λ(x : Natural) → 5 * x) 1
dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/1A.dhall view
@@ -1,1 +1,1 @@-λ(zero : Natural) → ../../../../../../Prelude/Natural/fold 3 Natural (λ(x : Natural) → 5 * x) zero+λ(zero : Natural) → ../../../../../../Prelude/Natural/fold.dhall 3 Natural (λ(x : Natural) → 5 * x) zero
dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/2A.dhall view
@@ -1,4 +1,4 @@   λ(natural : Type) → λ(succ : natural → natural) → λ(zero : natural)-→ ../../../../../../Prelude/Natural/fold 3 natural succ zero+→ ../../../../../../Prelude/Natural/fold.dhall 3 natural succ zero
dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/isZero 2+../../../../../../Prelude/Natural/isZero.dhall 2
dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/isZero 0+../../../../../../Prelude/Natural/isZero.dhall 0
dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/odd 3+../../../../../../Prelude/Natural/odd.dhall 3
dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/odd 0+../../../../../../Prelude/Natural/odd.dhall 0
dhall-lang/tests/semantic-hash/success/prelude/Natural/product/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/product [ 2, 3, 5 ]+../../../../../../Prelude/Natural/product.dhall [ 2, 3, 5 ]
dhall-lang/tests/semantic-hash/success/prelude/Natural/product/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/product ([] : List Natural)+../../../../../../Prelude/Natural/product.dhall ([] : List Natural)
dhall-lang/tests/semantic-hash/success/prelude/Natural/show/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/show 3+../../../../../../Prelude/Natural/show.dhall 3
dhall-lang/tests/semantic-hash/success/prelude/Natural/show/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/show 0+../../../../../../Prelude/Natural/show.dhall 0
dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/sum [ 2, 3, 5 ]+../../../../../../Prelude/Natural/sum.dhall [ 2, 3, 5 ]
dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/sum ([] : List Natural)+../../../../../../Prelude/Natural/sum.dhall ([] : List Natural)
dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/toDouble 3+../../../../../../Prelude/Natural/toDouble.dhall 3
dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/toDouble 0+../../../../../../Prelude/Natural/toDouble.dhall 0
dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/toInteger 3+../../../../../../Prelude/Natural/toInteger.dhall 3
dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/toInteger 0+../../../../../../Prelude/Natural/toInteger.dhall 0
dhall-lang/tests/semantic-hash/success/prelude/Optional/all/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/all Natural Natural/even (Some 3)+../../../../../../Prelude/Optional/all.dhall Natural Natural/even (Some 3)
dhall-lang/tests/semantic-hash/success/prelude/Optional/all/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/all Natural Natural/even (None Natural)+../../../../../../Prelude/Optional/all.dhall Natural Natural/even (None Natural)
dhall-lang/tests/semantic-hash/success/prelude/Optional/any/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/any Natural Natural/even (Some 2)+../../../../../../Prelude/Optional/any.dhall Natural Natural/even (Some 2)
dhall-lang/tests/semantic-hash/success/prelude/Optional/any/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/any Natural Natural/even (None Natural)+../../../../../../Prelude/Optional/any.dhall Natural Natural/even (None Natural)
dhall-lang/tests/semantic-hash/success/prelude/Optional/build/0A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/Optional/build+../../../../../../Prelude/Optional/build.dhall Natural ( λ(optional : Type) → λ(some : Natural → optional)
dhall-lang/tests/semantic-hash/success/prelude/Optional/build/1A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/Optional/build+../../../../../../Prelude/Optional/build.dhall Natural ( λ(optional : Type) → λ(some : Natural → optional)
dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/concat Natural (Some (Some 1))+../../../../../../Prelude/Optional/concat.dhall Natural (Some (Some 1))
dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/concat Natural (Some (None Natural))+../../../../../../Prelude/Optional/concat.dhall Natural (Some (None Natural))
dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/2A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/concat Natural (None (Optional Natural))+../../../../../../Prelude/Optional/concat.dhall Natural (None (Optional Natural))
dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/filter Natural Natural/even (Some 2)+../../../../../../Prelude/Optional/filter.dhall Natural Natural/even (Some 2)
dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/filter Natural Natural/odd (Some 2)+../../../../../../Prelude/Optional/filter.dhall Natural Natural/odd (Some 2)
dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/fold Natural (Some 2) Natural (λ(x : Natural) → x) 0+../../../../../../Prelude/Optional/fold.dhall Natural (Some 2) Natural (λ(x : Natural) → x) 0
dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/fold Natural (None Natural) Natural (λ(x : Natural) → x) 0+../../../../../../Prelude/Optional/fold.dhall Natural (None Natural) Natural (λ(x : Natural) → x) 0
dhall-lang/tests/semantic-hash/success/prelude/Optional/head/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/head Natural [ None Natural, Some 1, Some 2 ]+../../../../../../Prelude/Optional/head.dhall Natural [ None Natural, Some 1, Some 2 ]
dhall-lang/tests/semantic-hash/success/prelude/Optional/head/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/head Natural [ None Natural, None Natural ]+../../../../../../Prelude/Optional/head.dhall Natural [ None Natural, None Natural ]
dhall-lang/tests/semantic-hash/success/prelude/Optional/head/2A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/head Natural ([] : List (Optional Natural))+../../../../../../Prelude/Optional/head.dhall Natural ([] : List (Optional Natural))
dhall-lang/tests/semantic-hash/success/prelude/Optional/last/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/last Natural [ None Natural, Some 1, Some 2 ]+../../../../../../Prelude/Optional/last.dhall Natural [ None Natural, Some 1, Some 2 ]
dhall-lang/tests/semantic-hash/success/prelude/Optional/last/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/last Natural [ None Natural, None Natural ]+../../../../../../Prelude/Optional/last.dhall Natural [ None Natural, None Natural ]
dhall-lang/tests/semantic-hash/success/prelude/Optional/last/2A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/last Natural ([] : List (Optional Natural))+../../../../../../Prelude/Optional/last.dhall Natural ([] : List (Optional Natural))
dhall-lang/tests/semantic-hash/success/prelude/Optional/length/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/length Natural (Some 2)+../../../../../../Prelude/Optional/length.dhall Natural (Some 2)
dhall-lang/tests/semantic-hash/success/prelude/Optional/length/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/length Natural (None Natural)+../../../../../../Prelude/Optional/length.dhall Natural (None Natural)
dhall-lang/tests/semantic-hash/success/prelude/Optional/map/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/map Natural Bool Natural/even (Some 3)+../../../../../../Prelude/Optional/map.dhall Natural Bool Natural/even (Some 3)
dhall-lang/tests/semantic-hash/success/prelude/Optional/map/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/map Natural Bool Natural/even (None Natural)+../../../../../../Prelude/Optional/map.dhall Natural Bool Natural/even (None Natural)
dhall-lang/tests/semantic-hash/success/prelude/Optional/null/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/null Natural (Some 2)+../../../../../../Prelude/Optional/null.dhall Natural (Some 2)
dhall-lang/tests/semantic-hash/success/prelude/Optional/null/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/null Natural (None Natural)+../../../../../../Prelude/Optional/null.dhall Natural (None Natural)
dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/toList Natural (Some 1)+../../../../../../Prelude/Optional/toList.dhall Natural (Some 1)
dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/toList Natural (None Natural)+../../../../../../Prelude/Optional/toList.dhall Natural (None Natural)
dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/unzip Text Bool (Some { _1 = "ABC", _2 = True })+../../../../../../Prelude/Optional/unzip.dhall Text Bool (Some { _1 = "ABC", _2 = True })
dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/unzip Text Bool (None { _1 : Text, _2 : Bool })+../../../../../../Prelude/Optional/unzip.dhall Text Bool (None { _1 : Text, _2 : Bool })
dhall-lang/tests/semantic-hash/success/prelude/Text/concat/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/concat [ "ABC", "DEF", "GHI" ]+../../../../../../Prelude/Text/concat.dhall [ "ABC", "DEF", "GHI" ]
dhall-lang/tests/semantic-hash/success/prelude/Text/concat/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/concat ([] : List Text)+../../../../../../Prelude/Text/concat.dhall ([] : List Text)
dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/concatMap Natural (λ(n : Natural) → "${Natural/show n} ") [ 0, 1, 2 ]+../../../../../../Prelude/Text/concatMap.dhall Natural (λ(n : Natural) → "${Natural/show n} ") [ 0, 1, 2 ]
dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/concatMap Natural (λ(n : Natural) → "${Natural/show n} ") ([] : List Natural)+../../../../../../Prelude/Text/concatMap.dhall Natural (λ(n : Natural) → "${Natural/show n} ") ([] : List Natural)
dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/concatMapSep ", " Natural Natural/show [ 0, 1, 2 ]+../../../../../../Prelude/Text/concatMapSep.dhall ", " Natural Natural/show [ 0, 1, 2 ]
dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/concatMapSep ", " Natural Natural/show ([] : List Natural)+../../../../../../Prelude/Text/concatMapSep.dhall ", " Natural Natural/show ([] : List Natural)
dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/concatSep ", " [ "ABC", "DEF", "GHI" ]+../../../../../../Prelude/Text/concatSep.dhall ", " [ "ABC", "DEF", "GHI" ]
dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/concatSep ", " ([] : List Text)+../../../../../../Prelude/Text/concatSep.dhall ", " ([] : List Text)
dhall-lang/tests/semantic-hash/success/prelude/Text/show/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/show "ABC"+../../../../../../Prelude/Text/show.dhall "ABC"
dhall-lang/tests/semantic-hash/success/prelude/Text/show/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/show "\u0000 \$ \\ \n \u263a"+../../../../../../Prelude/Text/show.dhall "\u0000 \$ \\ \n \u263a"
+ dhall-lang/tests/type-inference/failure/DateApplyTime.dhall view
@@ -0,0 +1,3 @@+-- This parses, but will fail to type-check, because in the absence of the `T`+-- it is interpreted as a `Date` applied to a `Time`+2020-01-01 12:00:00
+ dhall-lang/tests/type-inference/failure/unit/AnnotationRecordWrongFieldName.dhall view
@@ -0,0 +1,1 @@+{ x = 1 } : { y : Natural }
+ dhall-lang/tests/type-inference/failure/unit/AnnotationRecordWrongFieldType.dhall view
@@ -0,0 +1,1 @@+{ x = 1 } : { x : Text }
+ dhall-lang/tests/type-inference/failure/unit/AssertAlphaTrap.dhall view
@@ -0,0 +1,1 @@+assert : (\(_: Bool) -> _) === (\(x: Bool) -> _)
+ dhall-lang/tests/type-inference/failure/unit/AssertAlphaTrap2.dhall view
@@ -0,0 +1,1 @@+\(_: Bool) -> assert : (\(_: Bool) -> _) === (\(x: Bool) -> _)
+ dhall-lang/tests/type-inference/failure/unit/AssertDoubleZeros.dhall view
@@ -0,0 +1,1 @@+assert : -0.0 ≡ +0.0
+ dhall-lang/tests/type-inference/failure/unit/AssertNotEquivalence.dhall view
@@ -0,0 +1,1 @@+assert : Bool
+ dhall-lang/tests/type-inference/failure/unit/AssertTriviallyFalse.dhall view
@@ -0,0 +1,1 @@+assert : 1 === 2
+ dhall-lang/tests/type-inference/failure/unit/CompletionMissingRequiredField.dhall view
@@ -0,0 +1,6 @@+let Example =+      { Type = { name : Text, id : Optional Natural }+      , default = { id = None Natural }+      }++in  Example::{=}
+ dhall-lang/tests/type-inference/failure/unit/CompletionWithWrongDefaultType.dhall view
@@ -0,0 +1,6 @@+let Example =+      { Type = { name : Text, id : Optional Natural }+      , default = { name = True, id = None Natural }+      }++in  Example::{=}
+ dhall-lang/tests/type-inference/failure/unit/CompletionWithWrongFieldName.dhall view
@@ -0,0 +1,6 @@+let Example =+      { Type = { name : Text, id : Optional Natural }+      , default = { name = "", id = None Natural }+      }++in  Example::{ nam = "John Doe" }
+ dhall-lang/tests/type-inference/failure/unit/CompletionWithWrongOverridenType.dhall view
@@ -0,0 +1,6 @@+let Example =+      { Type = { name : Text, id : Optional Natural }+      , default = { name = "", id = None Natural }+      }++in  Example::{ name = True }
+ dhall-lang/tests/type-inference/failure/unit/EmptyToMap.dhall view
@@ -0,0 +1,1 @@+toMap {=}
+ dhall-lang/tests/type-inference/failure/unit/EquivalenceNotSameType.dhall view
@@ -0,0 +1,1 @@+1 === False
+ dhall-lang/tests/type-inference/failure/unit/EquivalenceNotTerms.dhall view
@@ -0,0 +1,1 @@+Bool === Bool
+ dhall-lang/tests/type-inference/failure/unit/FunctionApplicationArgumentNotMatch.dhall view
@@ -0,0 +1,1 @@+(λ(_ : Natural) → _) True
+ dhall-lang/tests/type-inference/failure/unit/FunctionApplicationIsNotFunction.dhall view
@@ -0,0 +1,1 @@+True True
+ dhall-lang/tests/type-inference/failure/unit/FunctionArgumentTypeNotAType.dhall view
@@ -0,0 +1,1 @@+λ(_ : 1) → _
+ dhall-lang/tests/type-inference/failure/unit/FunctionTypeArgumentTypeNotAType.dhall view
@@ -0,0 +1,1 @@+2 → _
+ dhall-lang/tests/type-inference/failure/unit/FunctionTypeKindSort.dhall view
@@ -0,0 +1,1 @@+Kind → Sort
+ dhall-lang/tests/type-inference/failure/unit/FunctionTypeOutputTypeNotAType.dhall view
@@ -0,0 +1,1 @@+Bool -> 1
+ dhall-lang/tests/type-inference/failure/unit/FunctionTypeTypeSort.dhall view
@@ -0,0 +1,1 @@+Type → Sort
+ dhall-lang/tests/type-inference/failure/unit/HeterogenousToMap.dhall view
@@ -0,0 +1,1 @@+toMap { foo= 1, bar= "Bar" }
+ dhall-lang/tests/type-inference/failure/unit/IfBranchesNotMatch.dhall view
@@ -0,0 +1,1 @@+if True then 1 else ""
+ dhall-lang/tests/type-inference/failure/unit/IfBranchesNotTermTypeOrKind.dhall view
@@ -0,0 +1,1 @@+if True then Kind else Kind
+ dhall-lang/tests/type-inference/failure/unit/IfNotBool.dhall view
@@ -0,0 +1,1 @@+if 1 then 1 else 1
+ dhall-lang/tests/type-inference/failure/unit/LetInSort.dhall view
@@ -0,0 +1,1 @@+\(x: let x = 0 in Sort) -> 1
+ dhall-lang/tests/type-inference/failure/unit/LetWithNonterminatingAnnotation.dhall view
@@ -0,0 +1,14 @@+-- When you check if an inferred type is equivalent to an annotation,+-- you must alpha-beta-normalize both sides first.  But it is not safe+-- to beta-normalise an expression which hasn't first been+-- typechecked.+--+-- This test contains an annotation which doesn't typecheck, and+-- which, when beta-normalized, doesn't terminate.  It exists to+-- verify that implementations typecheck the annotation before+-- checking equivalence.+let a+    : (λ(x : Natural) → x x) (λ(x : Natural) → x x)+    = 3++in  5
+ dhall-lang/tests/type-inference/failure/unit/LetWithWrongAnnotation.dhall view
@@ -0,0 +1,1 @@+let x : Natural = True in True
+ dhall-lang/tests/type-inference/failure/unit/ListLiteralEmptyNotType.dhall view
@@ -0,0 +1,1 @@+[] : List Type
+ dhall-lang/tests/type-inference/failure/unit/ListLiteralNotType.dhall view
@@ -0,0 +1,1 @@+[ Bool ]
+ dhall-lang/tests/type-inference/failure/unit/ListLiteralTypesNotMatch.dhall view
@@ -0,0 +1,1 @@+[ True, 1 ]
+ dhall-lang/tests/type-inference/failure/unit/MergeAlternativeHasNoHandler.dhall view
@@ -0,0 +1,1 @@+merge {=} (< x : Bool >.x True)
+ dhall-lang/tests/type-inference/failure/unit/MergeAnnotationMismatch.dhall view
@@ -0,0 +1,1 @@+merge { x = 0 } < x >.x : Bool
+ dhall-lang/tests/type-inference/failure/unit/MergeAnnotationNotType.dhall view
@@ -0,0 +1,1 @@+merge {=} <> : Type
+ dhall-lang/tests/type-inference/failure/unit/MergeBool.dhall view
@@ -0,0 +1,1 @@+\(x: { True: Natural, False: Natural }) -> merge x True
+ dhall-lang/tests/type-inference/failure/unit/MergeEmptyNeedsDirectAnnotation1.dhall view
@@ -0,0 +1,1 @@+\(x: <>) -> (merge {=} x) : Bool
+ dhall-lang/tests/type-inference/failure/unit/MergeEmptyNeedsDirectAnnotation2.dhall view
@@ -0,0 +1,1 @@+\(x: <>) -> let y: Bool = merge {=} x in 1
+ dhall-lang/tests/type-inference/failure/unit/MergeEmptyWithoutAnnotation.dhall view
@@ -0,0 +1,1 @@+merge {=} <>
+ dhall-lang/tests/type-inference/failure/unit/MergeHandlerFreeVar.dhall view
@@ -0,0 +1,1 @@+merge { x = None } (<x: Type>.x Bool)
+ dhall-lang/tests/type-inference/failure/unit/MergeHandlerNotFunction.dhall view
@@ -0,0 +1,1 @@+merge { x = True } (< x : Bool >.x True)
+ dhall-lang/tests/type-inference/failure/unit/MergeHandlerNotInUnion.dhall view
@@ -0,0 +1,1 @@+merge { x = λ(_ : Bool) → _ } <> : Bool
+ dhall-lang/tests/type-inference/failure/unit/MergeHandlerNotMatchAlternativeType.dhall view
@@ -0,0 +1,1 @@+merge { x = λ(_ : Bool) → _ } (< x : Natural >.x 1)
+ dhall-lang/tests/type-inference/failure/unit/MergeHandlersWithDifferentType.dhall view
@@ -0,0 +1,1 @@+merge { x = λ(_ : Bool) → _, y = λ(_ : Natural) → _ } (< x : Bool | y : Natural >.x True)
+ dhall-lang/tests/type-inference/failure/unit/MergeLhsNotRecord.dhall view
@@ -0,0 +1,1 @@+merge True < x >.x
+ dhall-lang/tests/type-inference/failure/unit/MergeMissingHandler1.dhall view
@@ -0,0 +1,1 @@+merge {=} <x>.x
+ dhall-lang/tests/type-inference/failure/unit/MergeMissingHandler2.dhall view
@@ -0,0 +1,1 @@+merge { x = 0 } <x | y>.x
+ dhall-lang/tests/type-inference/failure/unit/MergeRhsNotUnion.dhall view
@@ -0,0 +1,1 @@+merge {=} True
+ dhall-lang/tests/type-inference/failure/unit/MergeUnusedHandler.dhall view
@@ -0,0 +1,1 @@+merge { x = 1, y = 2 } < x >.x
+ dhall-lang/tests/type-inference/failure/unit/MistypedToMap1.dhall view
@@ -0,0 +1,1 @@+toMap { foo= 1, bar= 4 } : Natural
+ dhall-lang/tests/type-inference/failure/unit/MistypedToMap2.dhall view
@@ -0,0 +1,1 @@+toMap { foo= 1, bar= 4 } : List Natural
+ dhall-lang/tests/type-inference/failure/unit/MistypedToMap3.dhall view
@@ -0,0 +1,1 @@+toMap { foo= 1, bar= 4 } : List { mapKey : Natural, mapValue : Natural }
+ dhall-lang/tests/type-inference/failure/unit/MistypedToMap4.dhall view
@@ -0,0 +1,1 @@+toMap { foo= 1, bar= 4 } : List { mapKey : Text, mapValue : Text }
+ dhall-lang/tests/type-inference/failure/unit/NaturalSubtractNotNatural.dhall view
@@ -0,0 +1,1 @@+Natural/subtract True True
+ dhall-lang/tests/type-inference/failure/unit/NestedAnnotInnerWrong.dhall view
@@ -0,0 +1,1 @@+(0 : Bool) : Natural
+ dhall-lang/tests/type-inference/failure/unit/NestedAnnotOuterWrong.dhall view
@@ -0,0 +1,1 @@+(0 : Natural) : Bool
+ dhall-lang/tests/type-inference/failure/unit/NonRecordToMap.dhall view
@@ -0,0 +1,1 @@+toMap "text"
+ dhall-lang/tests/type-inference/failure/unit/OperatorAndNotBool.dhall view
@@ -0,0 +1,1 @@+1 && 1
+ dhall-lang/tests/type-inference/failure/unit/OperatorEqualNotBool.dhall view
@@ -0,0 +1,1 @@+1 == 1
+ dhall-lang/tests/type-inference/failure/unit/OperatorListConcatenateLhsNotList.dhall view
@@ -0,0 +1,1 @@+1 # [ True ]
+ dhall-lang/tests/type-inference/failure/unit/OperatorListConcatenateListsNotMatch.dhall view
@@ -0,0 +1,1 @@+[ True ] # [ 1 ]
+ dhall-lang/tests/type-inference/failure/unit/OperatorListConcatenateNotListsButMatch.dhall view
@@ -0,0 +1,1 @@+1 # 2
+ dhall-lang/tests/type-inference/failure/unit/OperatorListConcatenateRhsNotList.dhall view
@@ -0,0 +1,1 @@+[ True ] # 1
+ dhall-lang/tests/type-inference/failure/unit/OperatorNotEqualNotBool.dhall view
@@ -0,0 +1,1 @@+1 != 1
+ dhall-lang/tests/type-inference/failure/unit/OperatorOrNotBool.dhall view
@@ -0,0 +1,1 @@+1 || 1
+ dhall-lang/tests/type-inference/failure/unit/OperatorPlusNotNatural.dhall view
@@ -0,0 +1,1 @@+True + True
+ dhall-lang/tests/type-inference/failure/unit/OperatorTextConcatenateLhsNotText.dhall view
@@ -0,0 +1,1 @@+1 ++ ""
+ dhall-lang/tests/type-inference/failure/unit/OperatorTextConcatenateRhsNotText.dhall view
@@ -0,0 +1,1 @@+"" ++ 1
+ dhall-lang/tests/type-inference/failure/unit/OperatorTimesNotNatural.dhall view
@@ -0,0 +1,1 @@+True * True
+ dhall-lang/tests/type-inference/failure/unit/OptionalDeprecatedSyntaxAbsent.dhall view
@@ -0,0 +1,1 @@+[] : Optional Bool
+ dhall-lang/tests/type-inference/failure/unit/OptionalDeprecatedSyntaxPresent.dhall view
@@ -0,0 +1,1 @@+[ 1 ] : Optional Natural
+ dhall-lang/tests/type-inference/failure/unit/RecordLitDuplicateFieldsAbstract.dhall view
@@ -0,0 +1,13 @@+{-  This test illustrates that duplicate fields need not be literals in order+    to be properly normalized.  One or both of the duplicate fields can be+    abstract because field duplication delegates its behavior to the `∧`+    operator++    This particular example fails because it desugars to:++        λ(r : { y : Natural }) → { x = { y = 1 } ∧ r }++    ... and the `∧` operator can infer that the two records collide on the+    field `y`+-}+λ(r : { y : Natural }) → { x = { y = 1 }, x = r }
+ dhall-lang/tests/type-inference/failure/unit/RecordLitDuplicateFieldsCollidingRecords.dhall view
@@ -0,0 +1,8 @@+{-  This fails because the expression desugars to:++        { x = { y = 0 } ∧ { y = 0 } }++    ... which is ill-typed due to `∧` forbidding collisions and the two `y`+    fields collide.+-}+{ x = { y = 0 }, x = { y = 0 } }
+ dhall-lang/tests/type-inference/failure/unit/RecordLitDuplicateFieldsNotRecords.dhall view
@@ -0,0 +1,7 @@+{-  This fails because the expression desugars to:++    { x = 0 ∧ 0 }++    ... which is ill-typed due to ∧ only working on records+-}+{ x = 0, x = 0 }
+ dhall-lang/tests/type-inference/failure/unit/RecordProjectionByTypeFieldTypeMismatch.dhall view
@@ -0,0 +1,1 @@+{ y = {=} }.( {y : Natural} )
+ dhall-lang/tests/type-inference/failure/unit/RecordProjectionByTypeNotPresent.dhall view
@@ -0,0 +1,1 @@+{ y = {=} }.( {x : Natural} )
+ dhall-lang/tests/type-inference/failure/unit/RecordProjectionDuplicateFields.dhall view
@@ -0,0 +1,1 @@+{ x = 1 }.{ x, x }
+ dhall-lang/tests/type-inference/failure/unit/RecordProjectionEmpty.dhall view
@@ -0,0 +1,1 @@+{=}.{ x }
+ dhall-lang/tests/type-inference/failure/unit/RecordProjectionNotPresent.dhall view
@@ -0,0 +1,1 @@+{ y = {=} }.{ x }
+ dhall-lang/tests/type-inference/failure/unit/RecordProjectionNotRecord.dhall view
@@ -0,0 +1,1 @@+True.{ x }
+ dhall-lang/tests/type-inference/failure/unit/RecordSelectionEmpty.dhall view
@@ -0,0 +1,1 @@+{=}.x
+ dhall-lang/tests/type-inference/failure/unit/RecordSelectionNotPresent.dhall view
@@ -0,0 +1,1 @@+{ y = {=} }.x
+ dhall-lang/tests/type-inference/failure/unit/RecordSelectionNotRecord.dhall view
@@ -0,0 +1,1 @@+True.x
+ dhall-lang/tests/type-inference/failure/unit/RecordSelectionTypeNotUnionType.dhall view
@@ -0,0 +1,1 @@+Bool.x
+ dhall-lang/tests/type-inference/failure/unit/RecordTypeDuplicateFields.dhall view
@@ -0,0 +1,1 @@+{ x: Natural, x: Natural }
+ dhall-lang/tests/type-inference/failure/unit/RecordTypeValueMember.dhall view
@@ -0,0 +1,1 @@+{ x : True }
+ dhall-lang/tests/type-inference/failure/unit/RecursiveRecordMergeLhsNotRecord.dhall view
@@ -0,0 +1,1 @@+True ∧ {=}
+ dhall-lang/tests/type-inference/failure/unit/RecursiveRecordMergeOverlapping.dhall view
@@ -0,0 +1,1 @@+{ x = True } ∧ { x = False }
+ dhall-lang/tests/type-inference/failure/unit/RecursiveRecordMergeRhsNotRecord.dhall view
@@ -0,0 +1,1 @@+{=} ∧ True
+ dhall-lang/tests/type-inference/failure/unit/RecursiveRecordTypeMergeLhsNotRecordType.dhall view
@@ -0,0 +1,1 @@+Bool ⩓ {}
+ dhall-lang/tests/type-inference/failure/unit/RecursiveRecordTypeMergeOverlapping.dhall view
@@ -0,0 +1,1 @@+{ x : Bool } ⩓ { x : Natural }
+ dhall-lang/tests/type-inference/failure/unit/RecursiveRecordTypeMergeRhsNotRecordType.dhall view
@@ -0,0 +1,1 @@+{} ⩓ Bool
+ dhall-lang/tests/type-inference/failure/unit/RemovedBuiltinOptionalBuild.dhall view
@@ -0,0 +1,1 @@+Optional/build
+ dhall-lang/tests/type-inference/failure/unit/RemovedBuiltinOptionalFold.dhall view
@@ -0,0 +1,1 @@+Optional/fold
+ dhall-lang/tests/type-inference/failure/unit/RightBiasedRecordMergeLhsNotRecord.dhall view
@@ -0,0 +1,1 @@+True ⫽ {=}
+ dhall-lang/tests/type-inference/failure/unit/RightBiasedRecordMergeRhsNotRecord.dhall view
@@ -0,0 +1,1 @@+{=} ⫽ True
+ dhall-lang/tests/type-inference/failure/unit/ShowConstructorNotFullyApplied.dhall view
@@ -0,0 +1,1 @@+showConstructor < A : Bool >.A
+ dhall-lang/tests/type-inference/failure/unit/ShowConstructorNotFullyAppliedOptional.dhall view
@@ -0,0 +1,1 @@+showConstructor None
+ dhall-lang/tests/type-inference/failure/unit/ShowConstructorWrongArgument.dhall view
@@ -0,0 +1,1 @@+showConstructor 0
+ dhall-lang/tests/type-inference/failure/unit/SomeNotType.dhall view
@@ -0,0 +1,1 @@+Some Bool
+ dhall-lang/tests/type-inference/failure/unit/Sort.dhall view
@@ -0,0 +1,1 @@+Sort
+ dhall-lang/tests/type-inference/failure/unit/TextLiteralInterpolateNotText.dhall view
@@ -0,0 +1,1 @@+"${1}"
+ dhall-lang/tests/type-inference/failure/unit/ToMapEmptyInvalidAnnotation.dhall view
@@ -0,0 +1,2 @@+-- The mapKey must be Text+toMap {=} : List { mapKey : Bool, mapValue : Text }
+ dhall-lang/tests/type-inference/failure/unit/ToMapWrongKind.dhall view
@@ -0,0 +1,1 @@+toMap { x = Bool }
+ dhall-lang/tests/type-inference/failure/unit/TypeAnnotationWrong.dhall view
@@ -0,0 +1,1 @@+1 : Bool
+ dhall-lang/tests/type-inference/failure/unit/UnionConstructorFieldNotPresent.dhall view
@@ -0,0 +1,1 @@+< x : Bool >.y
+ dhall-lang/tests/type-inference/failure/unit/UnionDeprecatedConstructorsKeyword.dhall view
@@ -0,0 +1,1 @@+constructors < Left : Natural | Right : Bool >
+ dhall-lang/tests/type-inference/failure/unit/UnionTypeDuplicateVariants1.dhall view
@@ -0,0 +1,1 @@+<x | x>
+ dhall-lang/tests/type-inference/failure/unit/UnionTypeDuplicateVariants2.dhall view
@@ -0,0 +1,1 @@+<x | x: Natural>
+ dhall-lang/tests/type-inference/failure/unit/UnionTypeNotType.dhall view
@@ -0,0 +1,1 @@+< x : True >
+ dhall-lang/tests/type-inference/failure/unit/VariableFree.dhall view
@@ -0,0 +1,1 @@+x
+ dhall-lang/tests/type-inference/failure/unit/WithInfersKind.dhall view
@@ -0,0 +1,1 @@+Some ({=} with x = Bool)
+ dhall-lang/tests/type-inference/failure/unit/WithInvalidOverrideA.dhall view
@@ -0,0 +1,6 @@+{-  The `with` keyword cannot "descend" past a field that is not a record++    In the following example, the `a` field is not a record, therefore there is+    no possibility of adding or overriding `a` with an inner `b` field+-}+{ a = 1 } with a.b = 2
+ dhall-lang/tests/type-inference/failure/unit/WithNotOptional.dhall view
@@ -0,0 +1,1 @@+{ x = 0 } with ? = 1
+ dhall-lang/tests/type-inference/failure/unit/WithNotRecord.dhall view
@@ -0,0 +1,1 @@+5 with a = 10
+ dhall-lang/tests/type-inference/failure/unit/WithOptionalRecordTypeChanged.dhall view
@@ -0,0 +1,1 @@+(None { x : Natural }) with ?.x = True
+ dhall-lang/tests/type-inference/failure/unit/WithOptionalTypeChanged.dhall view
@@ -0,0 +1,1 @@+(None Natural) with ? = "hello"
+ dhall-lang/tests/type-inference/failure/unit/Z.dhall view
@@ -0,0 +1,4 @@+-- The purpose of this test is to check that an implementation is not parsing a+-- standalone `Z` as a `TimeOffset`.  Instead, this should be treated as an+-- unbound variable named `Z`+Z
dhall-lang/tests/type-inference/success/prelude/Bool/and/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/and [ True, False, True ]+../../../../../../Prelude/Bool/and.dhall [ True, False, True ]
dhall-lang/tests/type-inference/success/prelude/Bool/and/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/and ([] : List Bool)+../../../../../../Prelude/Bool/and.dhall ([] : List Bool)
dhall-lang/tests/type-inference/success/prelude/Bool/build/0A.dhall view
@@ -1,2 +1,2 @@-../../../../../../Prelude/Bool/build +../../../../../../Prelude/Bool/build.dhall (λ(bool : Type) → λ(true : bool) → λ(false : bool) → true)
dhall-lang/tests/type-inference/success/prelude/Bool/build/1A.dhall view
@@ -1,2 +1,2 @@-../../../../../../Prelude/Bool/build +../../../../../../Prelude/Bool/build.dhall (λ(bool : Type) → λ(true : bool) → λ(false : bool) → false)
dhall-lang/tests/type-inference/success/prelude/Bool/even/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/even [ False, True, False ]+../../../../../../Prelude/Bool/even.dhall [ False, True, False ]
dhall-lang/tests/type-inference/success/prelude/Bool/even/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/even [ False, True ]+../../../../../../Prelude/Bool/even.dhall [ False, True ]
dhall-lang/tests/type-inference/success/prelude/Bool/even/2A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/even [ False ]+../../../../../../Prelude/Bool/even.dhall [ False ]
dhall-lang/tests/type-inference/success/prelude/Bool/even/3A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/even ([] : List Bool)+../../../../../../Prelude/Bool/even.dhall ([] : List Bool)
dhall-lang/tests/type-inference/success/prelude/Bool/fold/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/fold True Natural 0 1+../../../../../../Prelude/Bool/fold.dhall True Natural 0 1
dhall-lang/tests/type-inference/success/prelude/Bool/fold/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/fold False Natural 0 1+../../../../../../Prelude/Bool/fold.dhall False Natural 0 1
dhall-lang/tests/type-inference/success/prelude/Bool/not/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/not True+../../../../../../Prelude/Bool/not.dhall True
dhall-lang/tests/type-inference/success/prelude/Bool/not/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/not False+../../../../../../Prelude/Bool/not.dhall False
dhall-lang/tests/type-inference/success/prelude/Bool/odd/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/odd [ True, False, True ]+../../../../../../Prelude/Bool/odd.dhall [ True, False, True ]
dhall-lang/tests/type-inference/success/prelude/Bool/odd/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/odd [ True, False ]+../../../../../../Prelude/Bool/odd.dhall [ True, False ]
dhall-lang/tests/type-inference/success/prelude/Bool/odd/2A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/odd [ True ]+../../../../../../Prelude/Bool/odd.dhall [ True ]
dhall-lang/tests/type-inference/success/prelude/Bool/odd/3A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/odd ([] : List Bool)+../../../../../../Prelude/Bool/odd.dhall ([] : List Bool)
dhall-lang/tests/type-inference/success/prelude/Bool/or/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/or [ True, False, True ]+../../../../../../Prelude/Bool/or.dhall [ True, False, True ]
dhall-lang/tests/type-inference/success/prelude/Bool/or/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/or ([] : List Bool)+../../../../../../Prelude/Bool/or.dhall ([] : List Bool)
dhall-lang/tests/type-inference/success/prelude/Bool/show/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/show True+../../../../../../Prelude/Bool/show.dhall True
dhall-lang/tests/type-inference/success/prelude/Bool/show/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Bool/show False+../../../../../../Prelude/Bool/show.dhall False
dhall-lang/tests/type-inference/success/prelude/Double/show/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Double/show -3.1+../../../../../../Prelude/Double/show.dhall -3.1
dhall-lang/tests/type-inference/success/prelude/Double/show/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Double/show 0.4+../../../../../../Prelude/Double/show.dhall 0.4
dhall-lang/tests/type-inference/success/prelude/Integer/show/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Integer/show -3+../../../../../../Prelude/Integer/show.dhall -3
dhall-lang/tests/type-inference/success/prelude/Integer/show/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Integer/show +0+../../../../../../Prelude/Integer/show.dhall +0
dhall-lang/tests/type-inference/success/prelude/Integer/toDouble/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Integer/toDouble -3+../../../../../../Prelude/Integer/toDouble.dhall -3
dhall-lang/tests/type-inference/success/prelude/Integer/toDouble/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Integer/toDouble +2+../../../../../../Prelude/Integer/toDouble.dhall +2
dhall-lang/tests/type-inference/success/prelude/List/all/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/all Natural Natural/even [ 2, 3, 5 ]+../../../../../../Prelude/List/all.dhall Natural Natural/even [ 2, 3, 5 ]
dhall-lang/tests/type-inference/success/prelude/List/all/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/all Natural Natural/even ([] : List Natural)+../../../../../../Prelude/List/all.dhall Natural Natural/even ([] : List Natural)
dhall-lang/tests/type-inference/success/prelude/List/any/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/any Natural Natural/even [ 2, 3, 5 ]+../../../../../../Prelude/List/any.dhall Natural Natural/even [ 2, 3, 5 ]
dhall-lang/tests/type-inference/success/prelude/List/any/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/any Natural Natural/even ([] : List Natural)+../../../../../../Prelude/List/any.dhall Natural Natural/even ([] : List Natural)
dhall-lang/tests/type-inference/success/prelude/List/build/0A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/List/build+../../../../../../Prelude/List/build.dhall Text ( λ(list : Type) → λ(cons : Text → list → list)
dhall-lang/tests/type-inference/success/prelude/List/build/1A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/List/build+../../../../../../Prelude/List/build.dhall Text ( λ(list : Type) → λ(cons : Text → list → list)
dhall-lang/tests/type-inference/success/prelude/List/concat/0A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/List/concat Natural+../../../../../../Prelude/List/concat.dhall Natural [ [ 0, 1, 2 ] , [ 3, 4 ] , [ 5, 6, 7, 8 ]
dhall-lang/tests/type-inference/success/prelude/List/concat/1A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/List/concat Natural+../../../../../../Prelude/List/concat.dhall Natural [ [] : List Natural , [] : List Natural , [] : List Natural
dhall-lang/tests/type-inference/success/prelude/List/concatMap/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/concatMap Natural Natural (λ(n : Natural) → [ n, n ]) [ 2, 3, 5 ]+../../../../../../Prelude/List/concatMap.dhall Natural Natural (λ(n : Natural) → [ n, n ]) [ 2, 3, 5 ]
dhall-lang/tests/type-inference/success/prelude/List/concatMap/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/concatMap Natural Natural (λ(n : Natural) → [ n, n ]) ([] : List Natural)+../../../../../../Prelude/List/concatMap.dhall Natural Natural (λ(n : Natural) → [ n, n ]) ([] : List Natural)
dhall-lang/tests/type-inference/success/prelude/List/filter/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/filter Natural Natural/even [ 2, 3, 5 ]+../../../../../../Prelude/List/filter.dhall Natural Natural/even [ 2, 3, 5 ]
dhall-lang/tests/type-inference/success/prelude/List/filter/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/filter Natural Natural/odd [ 2, 3, 5 ]+../../../../../../Prelude/List/filter.dhall Natural Natural/odd [ 2, 3, 5 ]
dhall-lang/tests/type-inference/success/prelude/List/fold/0A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/List/fold+../../../../../../Prelude/List/fold.dhall Natural [ 2, 3, 5 ] Natural
dhall-lang/tests/type-inference/success/prelude/List/fold/1A.dhall view
@@ -1,5 +1,5 @@   λ(nil : Natural)-→ ../../../../../../Prelude/List/fold+→ ../../../../../../Prelude/List/fold.dhall   Natural   [ 2, 3, 5 ]   Natural
dhall-lang/tests/type-inference/success/prelude/List/fold/2A.dhall view
@@ -1,4 +1,4 @@   λ(list : Type) → λ(cons : Natural → list → list) → λ(nil : list)-→ ../../../../../../Prelude/List/fold Natural [ 2, 3, 5 ] list cons nil+→ ../../../../../../Prelude/List/fold.dhall Natural [ 2, 3, 5 ] list cons nil
dhall-lang/tests/type-inference/success/prelude/List/generate/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/generate 5 Bool Natural/even+../../../../../../Prelude/List/generate.dhall 5 Bool Natural/even
dhall-lang/tests/type-inference/success/prelude/List/generate/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/generate 0 Bool Natural/even+../../../../../../Prelude/List/generate.dhall 0 Bool Natural/even
dhall-lang/tests/type-inference/success/prelude/List/head/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/head Natural [ 0, 1, 2 ]+../../../../../../Prelude/List/head.dhall Natural [ 0, 1, 2 ]
dhall-lang/tests/type-inference/success/prelude/List/head/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/head Natural ([] : List Natural)+../../../../../../Prelude/List/head.dhall Natural ([] : List Natural)
dhall-lang/tests/type-inference/success/prelude/List/indexed/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/indexed Bool [ True, False, True ]+../../../../../../Prelude/List/indexed.dhall Bool [ True, False, True ]
dhall-lang/tests/type-inference/success/prelude/List/indexed/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/indexed Bool ([] : List Bool)+../../../../../../Prelude/List/indexed.dhall Bool ([] : List Bool)
dhall-lang/tests/type-inference/success/prelude/List/iterate/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/iterate 10 Natural (λ(x : Natural) → x * 2) 1+../../../../../../Prelude/List/iterate.dhall 10 Natural (λ(x : Natural) → x * 2) 1
dhall-lang/tests/type-inference/success/prelude/List/iterate/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/iterate 0 Natural (λ(x : Natural) → x * 2) 1+../../../../../../Prelude/List/iterate.dhall 0 Natural (λ(x : Natural) → x * 2) 1
dhall-lang/tests/type-inference/success/prelude/List/last/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/last Natural [ 0, 1, 2 ]+../../../../../../Prelude/List/last.dhall Natural [ 0, 1, 2 ]
dhall-lang/tests/type-inference/success/prelude/List/last/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/last Natural ([] : List Natural)+../../../../../../Prelude/List/last.dhall Natural ([] : List Natural)
dhall-lang/tests/type-inference/success/prelude/List/length/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/length Natural [ 0, 1, 2 ]+../../../../../../Prelude/List/length.dhall Natural [ 0, 1, 2 ]
dhall-lang/tests/type-inference/success/prelude/List/length/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/length Natural ([] : List Natural)+../../../../../../Prelude/List/length.dhall Natural ([] : List Natural)
dhall-lang/tests/type-inference/success/prelude/List/map/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/map Natural Bool Natural/even [ 2, 3, 5 ]+../../../../../../Prelude/List/map.dhall Natural Bool Natural/even [ 2, 3, 5 ]
dhall-lang/tests/type-inference/success/prelude/List/map/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/map Natural Bool Natural/even ([] : List Natural)+../../../../../../Prelude/List/map.dhall Natural Bool Natural/even ([] : List Natural)
dhall-lang/tests/type-inference/success/prelude/List/null/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/null Natural [ 0, 1, 2 ]+../../../../../../Prelude/List/null.dhall Natural [ 0, 1, 2 ]
dhall-lang/tests/type-inference/success/prelude/List/null/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/null Natural ([] : List Natural)+../../../../../../Prelude/List/null.dhall Natural ([] : List Natural)
dhall-lang/tests/type-inference/success/prelude/List/replicate/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/replicate 9 Natural 1+../../../../../../Prelude/List/replicate.dhall 9 Natural 1
dhall-lang/tests/type-inference/success/prelude/List/replicate/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/replicate 0 Natural 1+../../../../../../Prelude/List/replicate.dhall 0 Natural 1
dhall-lang/tests/type-inference/success/prelude/List/reverse/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/reverse Natural [ 0, 1, 2 ]+../../../../../../Prelude/List/reverse.dhall Natural [ 0, 1, 2 ]
dhall-lang/tests/type-inference/success/prelude/List/reverse/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/reverse Natural ([] : List Natural)+../../../../../../Prelude/List/reverse.dhall Natural ([] : List Natural)
dhall-lang/tests/type-inference/success/prelude/List/shifted/0A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/List/shifted+../../../../../../Prelude/List/shifted.dhall Bool [ [ { index = 0, value = True }   , { index = 1, value = True }
dhall-lang/tests/type-inference/success/prelude/List/shifted/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/shifted Bool ([] : List (List { index : Natural, value : Bool }))+../../../../../../Prelude/List/shifted.dhall Bool ([] : List (List { index : Natural, value : Bool }))
dhall-lang/tests/type-inference/success/prelude/List/unzip/0A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/List/unzip+../../../../../../Prelude/List/unzip.dhall Text Bool [ { _1 = "ABC", _2 = True }
dhall-lang/tests/type-inference/success/prelude/List/unzip/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/List/unzip Text Bool ([] : List { _1 : Text, _2 : Bool })+../../../../../../Prelude/List/unzip.dhall Text Bool ([] : List { _1 : Text, _2 : Bool })
dhall-lang/tests/type-inference/success/prelude/Natural/build/0A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/Natural/build+../../../../../../Prelude/Natural/build.dhall ( λ(natural : Type) → λ(succ : natural → natural) → λ(zero : natural)
dhall-lang/tests/type-inference/success/prelude/Natural/build/1A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/Natural/build+../../../../../../Prelude/Natural/build.dhall ( λ(natural : Type) → λ(succ : natural → natural) → λ(zero : natural)
dhall-lang/tests/type-inference/success/prelude/Natural/enumerate/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/enumerate 10+../../../../../../Prelude/Natural/enumerate.dhall 10
dhall-lang/tests/type-inference/success/prelude/Natural/enumerate/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/enumerate 0+../../../../../../Prelude/Natural/enumerate.dhall 0
dhall-lang/tests/type-inference/success/prelude/Natural/even/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/even 3+../../../../../../Prelude/Natural/even.dhall 3
dhall-lang/tests/type-inference/success/prelude/Natural/even/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/even 0+../../../../../../Prelude/Natural/even.dhall 0
dhall-lang/tests/type-inference/success/prelude/Natural/fold/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/fold 3 Natural (λ(x : Natural) → 5 * x) 1+../../../../../../Prelude/Natural/fold.dhall 3 Natural (λ(x : Natural) → 5 * x) 1
dhall-lang/tests/type-inference/success/prelude/Natural/fold/1A.dhall view
@@ -1,1 +1,1 @@-λ(zero : Natural) → ../../../../../../Prelude/Natural/fold 3 Natural (λ(x : Natural) → 5 * x) zero+λ(zero : Natural) → ../../../../../../Prelude/Natural/fold.dhall 3 Natural (λ(x : Natural) → 5 * x) zero
dhall-lang/tests/type-inference/success/prelude/Natural/fold/2A.dhall view
@@ -1,4 +1,4 @@   λ(natural : Type) → λ(succ : natural → natural) → λ(zero : natural)-→ ../../../../../../Prelude/Natural/fold 3 natural succ zero+→ ../../../../../../Prelude/Natural/fold.dhall 3 natural succ zero
dhall-lang/tests/type-inference/success/prelude/Natural/isZero/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/isZero 2+../../../../../../Prelude/Natural/isZero.dhall 2
dhall-lang/tests/type-inference/success/prelude/Natural/isZero/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/isZero 0+../../../../../../Prelude/Natural/isZero.dhall 0
dhall-lang/tests/type-inference/success/prelude/Natural/odd/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/odd 3+../../../../../../Prelude/Natural/odd.dhall 3
dhall-lang/tests/type-inference/success/prelude/Natural/odd/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/odd 0+../../../../../../Prelude/Natural/odd.dhall 0
dhall-lang/tests/type-inference/success/prelude/Natural/product/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/product [ 2, 3, 5 ]+../../../../../../Prelude/Natural/product.dhall [ 2, 3, 5 ]
dhall-lang/tests/type-inference/success/prelude/Natural/product/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/product ([] : List Natural)+../../../../../../Prelude/Natural/product.dhall ([] : List Natural)
dhall-lang/tests/type-inference/success/prelude/Natural/show/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/show 3+../../../../../../Prelude/Natural/show.dhall 3
dhall-lang/tests/type-inference/success/prelude/Natural/show/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/show 0+../../../../../../Prelude/Natural/show.dhall 0
dhall-lang/tests/type-inference/success/prelude/Natural/sum/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/sum [ 2, 3, 5 ]+../../../../../../Prelude/Natural/sum.dhall [ 2, 3, 5 ]
dhall-lang/tests/type-inference/success/prelude/Natural/sum/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/sum ([] : List Natural)+../../../../../../Prelude/Natural/sum.dhall ([] : List Natural)
dhall-lang/tests/type-inference/success/prelude/Natural/toDouble/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/toDouble 3+../../../../../../Prelude/Natural/toDouble.dhall 3
dhall-lang/tests/type-inference/success/prelude/Natural/toDouble/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/toDouble 0+../../../../../../Prelude/Natural/toDouble.dhall 0
dhall-lang/tests/type-inference/success/prelude/Natural/toInteger/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/toInteger 3+../../../../../../Prelude/Natural/toInteger.dhall 3
dhall-lang/tests/type-inference/success/prelude/Natural/toInteger/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Natural/toInteger 0+../../../../../../Prelude/Natural/toInteger.dhall 0
dhall-lang/tests/type-inference/success/prelude/Optional/all/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/all Natural Natural/even (Some 3)+../../../../../../Prelude/Optional/all.dhall Natural Natural/even (Some 3)
dhall-lang/tests/type-inference/success/prelude/Optional/all/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/all Natural Natural/even (None Natural)+../../../../../../Prelude/Optional/all.dhall Natural Natural/even (None Natural)
dhall-lang/tests/type-inference/success/prelude/Optional/any/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/any Natural Natural/even (Some 2)+../../../../../../Prelude/Optional/any.dhall Natural Natural/even (Some 2)
dhall-lang/tests/type-inference/success/prelude/Optional/any/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/any Natural Natural/even (None Natural)+../../../../../../Prelude/Optional/any.dhall Natural Natural/even (None Natural)
dhall-lang/tests/type-inference/success/prelude/Optional/build/0A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/Optional/build+../../../../../../Prelude/Optional/build.dhall Natural ( λ(optional : Type) → λ(some : Natural → optional)
dhall-lang/tests/type-inference/success/prelude/Optional/build/1A.dhall view
@@ -1,4 +1,4 @@-../../../../../../Prelude/Optional/build+../../../../../../Prelude/Optional/build.dhall Natural ( λ(optional : Type) → λ(some : Natural → optional)
dhall-lang/tests/type-inference/success/prelude/Optional/concat/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/concat Natural (Some (Some 1))+../../../../../../Prelude/Optional/concat.dhall Natural (Some (Some 1))
dhall-lang/tests/type-inference/success/prelude/Optional/concat/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/concat Natural (Some (None Natural))+../../../../../../Prelude/Optional/concat.dhall Natural (Some (None Natural))
dhall-lang/tests/type-inference/success/prelude/Optional/concat/2A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/concat Natural (None (Optional Natural))+../../../../../../Prelude/Optional/concat.dhall Natural (None (Optional Natural))
dhall-lang/tests/type-inference/success/prelude/Optional/filter/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/filter Natural Natural/even (Some 2)+../../../../../../Prelude/Optional/filter.dhall Natural Natural/even (Some 2)
dhall-lang/tests/type-inference/success/prelude/Optional/filter/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/filter Natural Natural/odd (Some 2)+../../../../../../Prelude/Optional/filter.dhall Natural Natural/odd (Some 2)
dhall-lang/tests/type-inference/success/prelude/Optional/fold/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/fold Natural (Some 2) Natural (λ(x : Natural) → x) 0+../../../../../../Prelude/Optional/fold.dhall Natural (Some 2) Natural (λ(x : Natural) → x) 0
dhall-lang/tests/type-inference/success/prelude/Optional/fold/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/fold Natural (None Natural) Natural (λ(x : Natural) → x) 0+../../../../../../Prelude/Optional/fold.dhall Natural (None Natural) Natural (λ(x : Natural) → x) 0
dhall-lang/tests/type-inference/success/prelude/Optional/head/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/head Natural [ None Natural, Some 1, Some 2 ]+../../../../../../Prelude/Optional/head.dhall Natural [ None Natural, Some 1, Some 2 ]
dhall-lang/tests/type-inference/success/prelude/Optional/head/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/head Natural [ None Natural, None Natural ]+../../../../../../Prelude/Optional/head.dhall Natural [ None Natural, None Natural ]
dhall-lang/tests/type-inference/success/prelude/Optional/head/2A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/head Natural ([] : List (Optional Natural))+../../../../../../Prelude/Optional/head.dhall Natural ([] : List (Optional Natural))
dhall-lang/tests/type-inference/success/prelude/Optional/last/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/last Natural [ None Natural, Some 1, Some 2 ]+../../../../../../Prelude/Optional/last.dhall Natural [ None Natural, Some 1, Some 2 ]
dhall-lang/tests/type-inference/success/prelude/Optional/last/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/last Natural [ None Natural, None Natural ]+../../../../../../Prelude/Optional/last.dhall Natural [ None Natural, None Natural ]
dhall-lang/tests/type-inference/success/prelude/Optional/last/2A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/last Natural ([] : List (Optional Natural))+../../../../../../Prelude/Optional/last.dhall Natural ([] : List (Optional Natural))
dhall-lang/tests/type-inference/success/prelude/Optional/length/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/length Natural (Some 2)+../../../../../../Prelude/Optional/length.dhall Natural (Some 2)
dhall-lang/tests/type-inference/success/prelude/Optional/length/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/length Natural (None Natural)+../../../../../../Prelude/Optional/length.dhall Natural (None Natural)
dhall-lang/tests/type-inference/success/prelude/Optional/map/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/map Natural Bool Natural/even (Some 3)+../../../../../../Prelude/Optional/map.dhall Natural Bool Natural/even (Some 3)
dhall-lang/tests/type-inference/success/prelude/Optional/map/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/map Natural Bool Natural/even (None Natural)+../../../../../../Prelude/Optional/map.dhall Natural Bool Natural/even (None Natural)
dhall-lang/tests/type-inference/success/prelude/Optional/null/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/null Natural (Some 2)+../../../../../../Prelude/Optional/null.dhall Natural (Some 2)
dhall-lang/tests/type-inference/success/prelude/Optional/null/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/null Natural (None Natural)+../../../../../../Prelude/Optional/null.dhall Natural (None Natural)
dhall-lang/tests/type-inference/success/prelude/Optional/toList/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/toList Natural (Some 1)+../../../../../../Prelude/Optional/toList.dhall Natural (Some 1)
dhall-lang/tests/type-inference/success/prelude/Optional/toList/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/toList Natural (None Natural)+../../../../../../Prelude/Optional/toList.dhall Natural (None Natural)
dhall-lang/tests/type-inference/success/prelude/Optional/unzip/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/unzip Text Bool (Some { _1 = "ABC", _2 = True })+../../../../../../Prelude/Optional/unzip.dhall Text Bool (Some { _1 = "ABC", _2 = True })
dhall-lang/tests/type-inference/success/prelude/Optional/unzip/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Optional/unzip Text Bool (None { _1 : Text, _2 : Bool })+../../../../../../Prelude/Optional/unzip.dhall Text Bool (None { _1 : Text, _2 : Bool })
dhall-lang/tests/type-inference/success/prelude/Text/concat/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/concat [ "ABC", "DEF", "GHI" ]+../../../../../../Prelude/Text/concat.dhall [ "ABC", "DEF", "GHI" ]
dhall-lang/tests/type-inference/success/prelude/Text/concat/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/concat ([] : List Text)+../../../../../../Prelude/Text/concat.dhall ([] : List Text)
dhall-lang/tests/type-inference/success/prelude/Text/concatMap/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/concatMap Natural (λ(n : Natural) → "${Natural/show n} ") [ 0, 1, 2 ]+../../../../../../Prelude/Text/concatMap.dhall Natural (λ(n : Natural) → "${Natural/show n} ") [ 0, 1, 2 ]
dhall-lang/tests/type-inference/success/prelude/Text/concatMap/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/concatMap Natural (λ(n : Natural) → "${Natural/show n} ") ([] : List Natural)+../../../../../../Prelude/Text/concatMap.dhall Natural (λ(n : Natural) → "${Natural/show n} ") ([] : List Natural)
dhall-lang/tests/type-inference/success/prelude/Text/concatMapSep/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/concatMapSep ", " Natural Natural/show [ 0, 1, 2 ]+../../../../../../Prelude/Text/concatMapSep.dhall ", " Natural Natural/show [ 0, 1, 2 ]
dhall-lang/tests/type-inference/success/prelude/Text/concatMapSep/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/concatMapSep ", " Natural Natural/show ([] : List Natural)+../../../../../../Prelude/Text/concatMapSep.dhall ", " Natural Natural/show ([] : List Natural)
dhall-lang/tests/type-inference/success/prelude/Text/concatSep/0A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/concatSep ", " [ "ABC", "DEF", "GHI" ]+../../../../../../Prelude/Text/concatSep.dhall ", " [ "ABC", "DEF", "GHI" ]
dhall-lang/tests/type-inference/success/prelude/Text/concatSep/1A.dhall view
@@ -1,1 +1,1 @@-../../../../../../Prelude/Text/concatSep ", " ([] : List Text)+../../../../../../Prelude/Text/concatSep.dhall ", " ([] : List Text)
dhall-lang/tests/type-inference/success/preludeB.dhall view
@@ -2,6 +2,7 @@     { and : ∀(xs : List Bool) → Bool     , build :         ∀(f : ∀(bool : Type) → ∀(true : bool) → ∀(false : bool) → bool) → Bool+    , equal : ∀(x : Bool) → ∀(y : Bool) → Bool     , even : ∀(xs : List Bool) → Bool     , fold :         ∀(b : Bool) → ∀(bool : Type) → ∀(true : bool) → ∀(false : bool) → bool@@ -10,16 +11,18 @@     , or : ∀(xs : List Bool) → Bool     , show : ∀(b : Bool) → Text     }+, Date : { show : Date → Text } , Double : { show : Double → Text } , Function :     { compose :-        ∀(A : Type) →-        ∀(B : Type) →-        ∀(C : Type) →-        ∀(f : A → B) →-        ∀(g : B → C) →-        ∀(x : A) →-          C+        ∀(a : Type) →+        ∀(b : Type) →+        ∀(c : Type) →+        ∀(f : a → b) →+        ∀(g : b → c) →+        ∀(x : a) →+          c+    , composeList : ∀(a : Type) → ∀(functions : List (a → a)) → a → a     , identity : ∀(a : Type) → ∀(x : a) → a     } , Integer :@@ -239,6 +242,22 @@               JSON           ) →           Text+    , renderCompact :+        ∀ ( j+          : ∀(JSON : Type) →+            ∀ ( json+              : { array : List JSON → JSON+                , bool : Bool → JSON+                , double : Double → JSON+                , integer : Integer → JSON+                , null : JSON+                , object : List { mapKey : Text, mapValue : JSON } → JSON+                , string : Text → JSON+                }+              ) →+              JSON+          ) →+          Text     , renderInteger : ∀(integer : Integer) → Text     , renderYAML :         ∀ ( json@@ -296,6 +315,12 @@     , drop : ∀(n : Natural) → ∀(a : Type) → ∀(xs : List a) → List a     , empty : ∀(a : Type) → List a     , filter : ∀(a : Type) → ∀(f : a → Bool) → ∀(xs : List a) → List a+    , filterMap :+        ∀(a : Type) →+        ∀(b : Type) →+        ∀(f : a → Optional b) →+        ∀(xs : List a) →+          List b     , fold :         ∀(a : Type) →         List a →@@ -303,6 +328,13 @@         ∀(cons : a → list → list) →         ∀(nil : list) →           list+    , foldLeft :+        ∀(a : Type) →+        ∀(xs : List a) →+        ∀(list : Type) →+        ∀(cons : list → a → list) →+        ∀(nil : list) →+          list     , generate : ∀(n : Natural) → ∀(a : Type) → ∀(f : Natural → a) → List a     , head : ∀(a : Type) → List a → Optional a     , index : ∀(n : Natural) → ∀(a : Type) → ∀(xs : List a) → Optional a@@ -311,6 +343,18 @@     , last : ∀(a : Type) → List a → Optional a     , length : ∀(a : Type) → List a → Natural     , map : ∀(a : Type) → ∀(b : Type) → ∀(f : a → b) → ∀(xs : List a) → List b+    , mapMaybe :+        ∀(a : Type) →+        ∀(b : Type) →+        ∀(f : a → Optional b) →+        ∀(xs : List a) →+          List b+    , mapWithIndex :+        ∀(a : Type) →+        ∀(b : Type) →+        ∀(f : Natural → a → b) →+        ∀(xs : List a) →+          List b     , null : ∀(a : Type) → ∀(xs : List a) → Bool     , partition :         ∀(a : Type) →@@ -361,6 +405,13 @@         ∀(f : a → b) →         ∀(m : List { mapKey : k, mapValue : a }) →           List { mapKey : k, mapValue : b }+    , mapMaybe :+        ∀(k : Type) →+        ∀(a : Type) →+        ∀(b : Type) →+        ∀(f : a → Optional b) →+        ∀(m : List { mapKey : k, mapValue : a }) →+          List { mapKey : k, mapValue : b }     , unpackOptionals :         ∀(k : Type) →         ∀(v : Type) →@@ -408,6 +459,102 @@     , toDouble : ∀(n : Natural) → Double     , toInteger : Natural → Integer     }+, NonEmpty :+    { Type : ∀(a : Type) → Type+    , all :+        ∀(a : Type) →+        ∀(f : a → Bool) →+        ∀(xs : { head : a, tail : List a }) →+          Bool+    , any :+        ∀(a : Type) →+        ∀(f : a → Bool) →+        ∀(xs : { head : a, tail : List a }) →+          Bool+    , concat :+        ∀(a : Type) →+        ∀ ( xss+          : { head : { head : a, tail : List a }+            , tail : List { head : a, tail : List a }+            }+          ) →+          { head : a, tail : List a }+    , concatMap :+        ∀(a : Type) →+        ∀(b : Type) →+        ∀(f : a → { head : b, tail : List b }) →+        ∀(xs : { head : a, tail : List a }) →+          { head : b, tail : List b }+    , head : ∀(a : Type) → ∀(xs : { head : a, tail : List a }) → a+    , index :+        ∀(n : Natural) →+        ∀(a : Type) →+        ∀(xs : { head : a, tail : List a }) →+          Optional a+    , indexed :+        ∀(a : Type) →+        ∀(xs : { head : a, tail : List a }) →+          { head : { index : Natural, value : a }+          , tail : List { index : Natural, value : a }+          }+    , last : ∀(a : Type) → ∀(xs : { head : a, tail : List a }) → a+    , length : ∀(a : Type) → ∀(xs : { head : a, tail : List a }) → Natural+    , make :+        ∀(a : Type) →+        ∀(head : a) →+        ∀(tail : List a) →+          { head : a, tail : List a }+    , map :+        ∀(a : Type) →+        ∀(b : Type) →+        ∀(f : a → b) →+        ∀(xs : { head : a, tail : List a }) →+          { head : b, tail : List b }+    , reverse :+        ∀(a : Type) →+        ∀(xs : { head : a, tail : List a }) →+          { head : a, tail : List a }+    , shifted :+        ∀(a : Type) →+        ∀ ( kvss+          : { head :+                { head : { index : Natural, value : a }+                , tail : List { index : Natural, value : a }+                }+            , tail :+                List+                  { head : { index : Natural, value : a }+                  , tail : List { index : Natural, value : a }+                  }+            }+          ) →+          { head : { index : Natural, value : a }+          , tail : List { index : Natural, value : a }+          }+    , singleton : ∀(a : Type) → ∀(x : a) → { head : a, tail : List a }+    , toList : ∀(a : Type) → ∀(xs : { head : a, tail : List a }) → List a+    , unzip :+        ∀(a : Type) →+        ∀(b : Type) →+        ∀(xs : { head : { _1 : a, _2 : b }, tail : List { _1 : a, _2 : b } }) →+          { _1 : { head : a, tail : List a }, _2 : { head : b, tail : List b } }+    , zip :+        ∀(a : Type) →+        ∀(xs : { head : a, tail : List a }) →+        ∀(b : Type) →+        ∀(ys : { head : b, tail : List b }) →+          { head : { _1 : a, _2 : b }, tail : List { _1 : a, _2 : b } }+    }+, Operator :+    { `!=` : ∀(m : Bool) → ∀(n : Bool) → Bool+    , `#` : ∀(type : Type) → ∀(m : List type) → ∀(n : List type) → List type+    , `&&` : ∀(m : Bool) → ∀(n : Bool) → Bool+    , `*` : ∀(m : Natural) → ∀(n : Natural) → Natural+    , `+` : ∀(m : Natural) → ∀(n : Natural) → Natural+    , `++` : ∀(m : Text) → ∀(n : Text) → Text+    , `==` : ∀(m : Bool) → ∀(n : Bool) → Bool+    , `||` : ∀(m : Bool) → ∀(n : Bool) → Bool+    } , Optional :     { all : ∀(a : Type) → ∀(f : a → Bool) → ∀(xs : Optional a) → Bool     , any : ∀(a : Type) → ∀(f : a → Bool) → ∀(xs : Optional a) → Bool@@ -421,7 +568,19 @@           ) →           Optional a     , concat : ∀(a : Type) → ∀(x : Optional (Optional a)) → Optional a+    , concatMap :+        ∀(a : Type) →+        ∀(b : Type) →+        ∀(f : a → Optional b) →+        ∀(o : Optional a) →+          Optional b     , default : ∀(a : Type) → ∀(default : a) → ∀(o : Optional a) → a+    , equal :+        ∀(a : Type) →+        ∀(compare : a → a → Bool) →+        ∀(ox : Optional a) →+        ∀(oy : Optional a) →+          Bool     , filter : ∀(a : Type) → ∀(f : a → Bool) → ∀(xs : Optional a) → Optional a     , fold :         ∀(a : Type) →@@ -459,10 +618,17 @@     , concatSep : ∀(separator : Text) → ∀(elements : List Text) → Text     , default : ∀(o : Optional Text) → Text     , defaultMap : ∀(a : Type) → ∀(f : a → Text) → ∀(o : Optional a) → Text+    , lowerASCII : ∀(nil : Text) → Text+    , replace :+        ∀(needle : Text) → ∀(replacement : Text) → ∀(haystack : Text) → Text     , replicate : ∀(num : Natural) → ∀(text : Text) → Text+    , shell-escape : ∀(xs : Text) → Text     , show : Text → Text     , spaces : ∀(a : Natural) → Text+    , upperASCII : ∀(nil : Text) → Text     }+, Time : { show : Time → Text }+, TimeZone : { show : TimeZone → Text } , XML :     { Type : Type     , attribute :@@ -481,6 +647,7 @@                             , name : Text                             } →                               XML+                        , rawText : Text → XML                         , text : Text → XML                         }                       ) →@@ -497,6 +664,7 @@                 , name : Text                 } →                   XML+            , rawText : Text → XML             , text : Text → XML             }           ) →@@ -516,10 +684,26 @@                 , name : Text                 } →                   XML+            , rawText : Text → XML             , text : Text → XML             }           ) →           XML+    , rawText :+        ∀(d : Text) →+        ∀(XML : Type) →+        ∀ ( xml+          : { element :+                { attributes : List { mapKey : Text, mapValue : Text }+                , content : List XML+                , name : Text+                } →+                  XML+            , rawText : Text → XML+            , text : Text → XML+            }+          ) →+          XML     , render :         ∀ ( x           : ∀(XML : Type) →@@ -530,6 +714,7 @@                     , name : Text                     } →                       XML+                , rawText : Text → XML                 , text : Text → XML                 }               ) →@@ -546,6 +731,7 @@                 , name : Text                 } →                   XML+            , rawText : Text → XML             , text : Text → XML             }           ) →
+ dhall-lang/tests/type-inference/success/unit/BytesLiteralA.dhall view
@@ -0,0 +1,1 @@+0x"0123456789abcdefABCDEF"
+ dhall-lang/tests/type-inference/success/unit/BytesLiteralB.dhall view
@@ -0,0 +1,1 @@+Bytes
+ dhall-lang/tests/type-inference/success/unit/ConstructorShiftA.dhall view
@@ -0,0 +1,1 @@+λ(t : Type) → < t : t >.t
+ dhall-lang/tests/type-inference/success/unit/ConstructorShiftB.dhall view
@@ -0,0 +1,1 @@+∀(t : Type) → ∀(t : t) → < t : t@1 >
+ dhall-lang/tests/type-inference/success/unit/IfBranchesKindA.dhall view
@@ -0,0 +1,1 @@+if True then (Type -> Type) else Type
+ dhall-lang/tests/type-inference/success/unit/IfBranchesKindB.dhall view
@@ -0,0 +1,1 @@+Kind
+ dhall-lang/tests/type-inference/success/unit/IfBranchesTypeA.dhall view
@@ -0,0 +1,1 @@+if True then Bool else Natural
+ dhall-lang/tests/type-inference/success/unit/IfBranchesTypeB.dhall view
@@ -0,0 +1,1 @@+Type
dhall-lang/tests/type-inference/success/unit/MergeOneWithAnnotation1A.dhall view
@@ -1,1 +1,1 @@-merge { x = λ(y : Bool) → y } < x >.x : (Bool → Bool)+merge { x = λ(y : Bool) → y } < x >.x : (∀(y : Bool) → Bool)
+ dhall-lang/tests/type-inference/success/unit/ShowConstructorEmptyA.dhall view
@@ -0,0 +1,1 @@+showConstructor <A>.A
+ dhall-lang/tests/type-inference/success/unit/ShowConstructorEmptyB.dhall view
@@ -0,0 +1,1 @@+Text
+ dhall-lang/tests/type-inference/success/unit/ShowConstructorNonEmptyA.dhall view
@@ -0,0 +1,1 @@+showConstructor (< A : Bool>.A False)
+ dhall-lang/tests/type-inference/success/unit/ShowConstructorNonEmptyB.dhall view
@@ -0,0 +1,1 @@+Text
+ dhall-lang/tests/type-inference/success/unit/ShowConstructorOptionalA.dhall view
@@ -0,0 +1,1 @@+showConstructor (Some 0)
+ dhall-lang/tests/type-inference/success/unit/ShowConstructorOptionalB.dhall view
@@ -0,0 +1,1 @@+Text
dhall-lang/tests/type-inference/success/unit/ToMapInferTypeFromRecordA.dhall view
@@ -1,1 +1,1 @@-toMap { x = λ(x : Bool) → x } : List { mapKey : Text, mapValue : Bool → Bool }+toMap { x = λ(x : Bool) → x } : List { mapKey : Text, mapValue : ∀(x : Bool) → Bool }
dhall-lang/tests/type-inference/success/unit/TypeAnnotationFunctionA.dhall view
@@ -1,1 +1,1 @@-(λ(x : Bool) → x) : Bool → Bool+(λ(x : Bool) → x) : ∀(x : Bool) → Bool
+ dhall-lang/tests/type-inference/success/unit/WithInfersKindA.dhall view
@@ -0,0 +1,1 @@+Some ({ x = Bool } with x = 0)
+ dhall-lang/tests/type-inference/success/unit/WithInfersKindB.dhall view
@@ -0,0 +1,1 @@+Optional { x : Natural }
+ dhall-lang/tests/type-inference/success/unit/WithOptionalTypeUnchangedA.dhall view
@@ -0,0 +1,1 @@+(Some 0) with ? = 1
+ dhall-lang/tests/type-inference/success/unit/WithOptionalTypeUnchangedB.dhall view
@@ -0,0 +1,1 @@+Optional Natural
+ dhall-lang/tests/type-inference/success/unit/time/DateA.dhall view
@@ -0,0 +1,1 @@+Date
+ dhall-lang/tests/type-inference/success/unit/time/DateB.dhall view
@@ -0,0 +1,1 @@+Type
+ dhall-lang/tests/type-inference/success/unit/time/DateLiteralA.dhall view
@@ -0,0 +1,1 @@+2000-01-01
+ dhall-lang/tests/type-inference/success/unit/time/DateLiteralB.dhall view
@@ -0,0 +1,1 @@+Date
+ dhall-lang/tests/type-inference/success/unit/time/DateTimeLiteralA.dhall view
@@ -0,0 +1,1 @@+2000-01-01T12:00:00
+ dhall-lang/tests/type-inference/success/unit/time/DateTimeLiteralB.dhall view
@@ -0,0 +1,1 @@+{ date : Date, time : Time }
+ dhall-lang/tests/type-inference/success/unit/time/DateTimeTimeZoneLiteralA.dhall view
@@ -0,0 +1,1 @@+2000-01-01T12:00:00+08:00
+ dhall-lang/tests/type-inference/success/unit/time/DateTimeTimeZoneLiteralB.dhall view
@@ -0,0 +1,1 @@+{ date : Date, time : Time, timeZone : TimeZone }
+ dhall-lang/tests/type-inference/success/unit/time/TimeA.dhall view
@@ -0,0 +1,1 @@+Time
+ dhall-lang/tests/type-inference/success/unit/time/TimeB.dhall view
@@ -0,0 +1,1 @@+Type
+ dhall-lang/tests/type-inference/success/unit/time/TimeLiteralA.dhall view
@@ -0,0 +1,1 @@+12:00:00
+ dhall-lang/tests/type-inference/success/unit/time/TimeLiteralB.dhall view
@@ -0,0 +1,1 @@+Time
+ dhall-lang/tests/type-inference/success/unit/time/TimeTimeZoneLiteralA.dhall view
@@ -0,0 +1,1 @@+12:00:00+08:00
+ dhall-lang/tests/type-inference/success/unit/time/TimeTimeZoneLiteralB.dhall view
@@ -0,0 +1,1 @@+{ time : Time, timeZone : TimeZone }
+ dhall-lang/tests/type-inference/success/unit/time/TimeZoneA.dhall view
@@ -0,0 +1,1 @@+TimeZone
+ dhall-lang/tests/type-inference/success/unit/time/TimeZoneB.dhall view
@@ -0,0 +1,1 @@+Type
+ dhall-lang/tests/type-inference/success/unit/time/TimeZoneLiteralA.dhall view
@@ -0,0 +1,1 @@++08:00
+ dhall-lang/tests/type-inference/success/unit/time/TimeZoneLiteralB.dhall view
@@ -0,0 +1,1 @@+TimeZone
dhall.cabal view
@@ -1,13 +1,12 @@+Cabal-Version: 2.4 Name: dhall-Version: 1.36.0-Cabal-Version: >=1.10+Version: 1.42.3 Build-Type: Simple-Tested-With: GHC == 8.4.3, GHC == 8.6.1-License: BSD3+License: BSD-3-Clause License-File: LICENSE-Copyright: 2017 Gabriel Gonzalez-Author: Gabriel Gonzalez-Maintainer: Gabriel439@gmail.com+Copyright: 2017 Gabriella Gonzalez+Author: Gabriella Gonzalez+Maintainer: GenuineGabriella@gmail.com Bug-Reports: https://github.com/dhall-lang/dhall-haskell/issues Synopsis: A configuration language guaranteed to terminate Description:@@ -25,10 +24,10 @@ Data-Files:     man/dhall.1 Extra-Source-Files:-    benchmark/deep-nested-large-record/*.dhall-    benchmark/examples/*.dhall-    benchmark/examples/normalize/*.dhall     CHANGELOG.md+    benchmark/**/*.dhall+    benchmark/**/*.dhallb+    dhall-lang/Prelude/**/*.dhall     dhall-lang/Prelude/Bool/and     dhall-lang/Prelude/Bool/build     dhall-lang/Prelude/Bool/even@@ -36,16 +35,10 @@     dhall-lang/Prelude/Bool/not     dhall-lang/Prelude/Bool/odd     dhall-lang/Prelude/Bool/or-    dhall-lang/Prelude/Bool/package.dhall     dhall-lang/Prelude/Bool/show-    dhall-lang/Prelude/Bool/*.dhall-    dhall-lang/Prelude/Double/package.dhall     dhall-lang/Prelude/Double/show-    dhall-lang/Prelude/Double/*.dhall     dhall-lang/Prelude/Function/compose     dhall-lang/Prelude/Function/identity-    dhall-lang/Prelude/Function/package.dhall-    dhall-lang/Prelude/Function/*.dhall     dhall-lang/Prelude/Integer/abs     dhall-lang/Prelude/Integer/add     dhall-lang/Prelude/Integer/clamp@@ -59,20 +52,17 @@     dhall-lang/Prelude/Integer/negative     dhall-lang/Prelude/Integer/nonNegative     dhall-lang/Prelude/Integer/nonPositive-    dhall-lang/Prelude/Integer/package.dhall     dhall-lang/Prelude/Integer/positive     dhall-lang/Prelude/Integer/show     dhall-lang/Prelude/Integer/subtract     dhall-lang/Prelude/Integer/toDouble     dhall-lang/Prelude/Integer/toNatural-    dhall-lang/Prelude/Integer/*.dhall     dhall-lang/Prelude/JSON/Format     dhall-lang/Prelude/JSON/Nesting     dhall-lang/Prelude/JSON/Tagged     dhall-lang/Prelude/JSON/Type     dhall-lang/Prelude/JSON/array     dhall-lang/Prelude/JSON/bool-    dhall-lang/Prelude/JSON/core.dhall     dhall-lang/Prelude/JSON/double     dhall-lang/Prelude/JSON/integer     dhall-lang/Prelude/JSON/keyText@@ -82,15 +72,12 @@     dhall-lang/Prelude/JSON/number     dhall-lang/Prelude/JSON/object     dhall-lang/Prelude/JSON/omitNullFields-    dhall-lang/Prelude/JSON/package.dhall     dhall-lang/Prelude/JSON/render     dhall-lang/Prelude/JSON/renderAs-    dhall-lang/Prelude/JSON/renderInteger.dhall     dhall-lang/Prelude/JSON/renderYAML     dhall-lang/Prelude/JSON/string     dhall-lang/Prelude/JSON/tagInline     dhall-lang/Prelude/JSON/tagNested-    dhall-lang/Prelude/JSON/*.dhall     dhall-lang/Prelude/List/all     dhall-lang/Prelude/List/any     dhall-lang/Prelude/List/build@@ -110,7 +97,6 @@     dhall-lang/Prelude/List/length     dhall-lang/Prelude/List/map     dhall-lang/Prelude/List/null-    dhall-lang/Prelude/List/package.dhall     dhall-lang/Prelude/List/partition     dhall-lang/Prelude/List/replicate     dhall-lang/Prelude/List/reverse@@ -119,10 +105,7 @@     dhall-lang/Prelude/List/unpackOptionals     dhall-lang/Prelude/List/unzip     dhall-lang/Prelude/List/zip-    dhall-lang/Prelude/List/*.dhall     dhall-lang/Prelude/Location/Type-    dhall-lang/Prelude/Location/package.dhall-    dhall-lang/Prelude/Location/*.dhall     dhall-lang/Prelude/Map/Entry     dhall-lang/Prelude/Map/Type     dhall-lang/Prelude/Map/empty@@ -130,9 +113,7 @@     dhall-lang/Prelude/Map/keyValue     dhall-lang/Prelude/Map/keys     dhall-lang/Prelude/Map/map-    dhall-lang/Prelude/Map/package.dhall     dhall-lang/Prelude/Map/values-    dhall-lang/Prelude/Map/*.dhall     dhall-lang/Prelude/Monoid     dhall-lang/Prelude/Natural/build     dhall-lang/Prelude/Natural/enumerate@@ -149,7 +130,6 @@     dhall-lang/Prelude/Natural/max     dhall-lang/Prelude/Natural/min     dhall-lang/Prelude/Natural/odd-    dhall-lang/Prelude/Natural/package.dhall     dhall-lang/Prelude/Natural/product     dhall-lang/Prelude/Natural/show     dhall-lang/Prelude/Natural/sort@@ -157,7 +137,6 @@     dhall-lang/Prelude/Natural/sum     dhall-lang/Prelude/Natural/toDouble     dhall-lang/Prelude/Natural/toInteger-    dhall-lang/Prelude/Natural/*.dhall     dhall-lang/Prelude/Optional/all     dhall-lang/Prelude/Optional/any     dhall-lang/Prelude/Optional/build@@ -170,281 +149,34 @@     dhall-lang/Prelude/Optional/length     dhall-lang/Prelude/Optional/map     dhall-lang/Prelude/Optional/null-    dhall-lang/Prelude/Optional/package.dhall     dhall-lang/Prelude/Optional/toList     dhall-lang/Prelude/Optional/unzip-    dhall-lang/Prelude/Optional/*.dhall     dhall-lang/Prelude/Text/concat     dhall-lang/Prelude/Text/concatMap     dhall-lang/Prelude/Text/concatMapSep     dhall-lang/Prelude/Text/concatSep     dhall-lang/Prelude/Text/default     dhall-lang/Prelude/Text/defaultMap-    dhall-lang/Prelude/Text/package.dhall     dhall-lang/Prelude/Text/replicate     dhall-lang/Prelude/Text/show     dhall-lang/Prelude/Text/spaces-    dhall-lang/Prelude/Text/*.dhall     dhall-lang/Prelude/XML/Type     dhall-lang/Prelude/XML/attribute     dhall-lang/Prelude/XML/element     dhall-lang/Prelude/XML/emptyAttributes     dhall-lang/Prelude/XML/leaf-    dhall-lang/Prelude/XML/package.dhall     dhall-lang/Prelude/XML/render     dhall-lang/Prelude/XML/text-    dhall-lang/Prelude/XML/*.dhall-    dhall-lang/Prelude/*.dhall-    dhall-lang/Prelude/package.dhall-    dhall-lang/tests/alpha-normalization/success/unit/*.dhall-    dhall-lang/tests/alpha-normalization/success/regression/*.dhall-    dhall-lang/tests/binary-decode/failure/unit/*.dhallb-    dhall-lang/tests/binary-decode/success/unit/*.dhall-    dhall-lang/tests/binary-decode/success/unit/*.dhallb-    dhall-lang/tests/binary-decode/success/unit/imports/*.dhall-    dhall-lang/tests/binary-decode/success/unit/imports/*.dhallb+    dhall-lang/tests/**/*.dhall+    dhall-lang/tests/**/*.dhallb+    dhall-lang/tests/**/*.hash+    dhall-lang/tests/**/*.txt+    dhall-lang/tests/**/*.bin     dhall-lang/tests/import/cache/dhall/12203871180b87ecaba8b53fffb2a8b52d3fce98098fab09a6f759358b9e8042eedc     dhall-lang/tests/import/cache/dhall/1220618f785ce8f3930a9144398f576f0a992544b51212bc9108c31b4e670dc6ed21-    dhall-lang/tests/import/data/*.dhall-    dhall-lang/tests/import/data/*.txt-    dhall-lang/tests/import/failure/*.dhall-    dhall-lang/tests/import/failure/unit/*.dhall-    dhall-lang/tests/import/success/*.dhall-    dhall-lang/tests/import/success/unit/*.dhall-    dhall-lang/tests/import/success/unit/asLocation/*.dhall-    dhall-lang/tests/normalization/success/*.dhall-    dhall-lang/tests/normalization/success/haskell-tutorial/access/*.dhall-    dhall-lang/tests/normalization/success/haskell-tutorial/combineTypes/*.dhall-    dhall-lang/tests/normalization/success/haskell-tutorial/prefer/*.dhall-    dhall-lang/tests/normalization/success/haskell-tutorial/projection/*.dhall-    dhall-lang/tests/normalization/success/regression/*.dhall-    dhall-lang/tests/normalization/success/simple/*.dhall-    dhall-lang/tests/normalization/success/simplifications/*.dhall-    dhall-lang/tests/normalization/success/unit/*.dhall-    dhall-lang/tests/parser/failure/*.dhall-    dhall-lang/tests/parser/failure/spacing/*.dhall-    dhall-lang/tests/parser/failure/unit/*.dhall-    dhall-lang/tests/parser/success/*.dhall-    dhall-lang/tests/parser/success/*.dhallb-    dhall-lang/tests/parser/success/text/*.dhall-    dhall-lang/tests/parser/success/text/*.dhallb-    dhall-lang/tests/parser/success/unit/*.dhall-    dhall-lang/tests/parser/success/unit/*.dhallb-    dhall-lang/tests/parser/success/unit/operators/*.dhall-    dhall-lang/tests/parser/success/unit/operators/*.dhallb-    dhall-lang/tests/parser/success/unit/import/*.dhall-    dhall-lang/tests/parser/success/unit/import/*.dhallb-    dhall-lang/tests/parser/success/unit/import/urls/*.dhall-    dhall-lang/tests/parser/success/unit/import/urls/*.dhallb-    dhall-lang/tests/semantic-hash/success/*.dhall-    dhall-lang/tests/semantic-hash/success/*.hash-    dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/*.dhall-    dhall-lang/tests/semantic-hash/success/haskell-tutorial/access/*.hash-    dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/*.dhall-    dhall-lang/tests/semantic-hash/success/haskell-tutorial/combineTypes/*.hash-    dhall-lang/tests/semantic-hash/success/haskell-tutorial/prefer/*.dhall-    dhall-lang/tests/semantic-hash/success/haskell-tutorial/prefer/*.hash-    dhall-lang/tests/semantic-hash/success/haskell-tutorial/projection/*.dhall-    dhall-lang/tests/semantic-hash/success/haskell-tutorial/projection/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Bool/and/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Bool/and/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Bool/build/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Bool/build/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Bool/even/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Bool/even/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Bool/fold/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Bool/not/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Bool/not/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Bool/odd/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Bool/or/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Bool/or/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Bool/show/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Bool/show/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Double/show/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Double/show/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Integer/show/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Integer/show/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Integer/toDouble/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/all/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/all/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/any/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/any/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/build/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/build/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/concat/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/concat/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/concatMap/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/filter/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/filter/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/fold/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/fold/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/generate/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/generate/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/head/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/head/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/indexed/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/indexed/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/iterate/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/iterate/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/last/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/last/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/length/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/length/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/map/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/map/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/null/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/null/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/replicate/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/replicate/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/reverse/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/reverse/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/shifted/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/shifted/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/List/unzip/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/List/unzip/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Natural/build/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Natural/build/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Natural/enumerate/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Natural/even/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Natural/even/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Natural/fold/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Natural/isZero/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Natural/odd/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Natural/product/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Natural/product/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Natural/show/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Natural/show/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Natural/sum/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Natural/toDouble/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Natural/toInteger/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Optional/all/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Optional/all/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Optional/any/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Optional/any/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Optional/build/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Optional/build/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Optional/concat/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Optional/filter/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Optional/fold/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Optional/head/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Optional/head/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Optional/last/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Optional/last/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Optional/length/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Optional/length/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Optional/map/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Optional/map/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Optional/null/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Optional/null/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Optional/toList/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Optional/unzip/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Text/concat/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Text/concat/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Text/concatMap/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Text/concatMapSep/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Text/concatSep/*.hash-    dhall-lang/tests/semantic-hash/success/prelude/Text/show/*.dhall-    dhall-lang/tests/semantic-hash/success/prelude/Text/show/*.hash-    dhall-lang/tests/semantic-hash/success/simple/*.dhall-    dhall-lang/tests/semantic-hash/success/simple/*.hash-    dhall-lang/tests/semantic-hash/success/simplifications/*.dhall-    dhall-lang/tests/semantic-hash/success/simplifications/*.hash-    dhall-lang/tests/type-inference/failure/*.dhall-    dhall-lang/tests/type-inference/success/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Bool/and/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Bool/build/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Bool/even/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Bool/fold/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Bool/not/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Bool/odd/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Bool/or/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Bool/show/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Double/show/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Integer/show/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Integer/toDouble/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/all/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/any/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/build/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/concat/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/concatMap/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/filter/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/fold/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/generate/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/head/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/indexed/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/iterate/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/last/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/length/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/map/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/null/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/replicate/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/reverse/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/shifted/*.dhall-    dhall-lang/tests/type-inference/success/prelude/List/unzip/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Monoid/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Natural/build/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Natural/enumerate/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Natural/even/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Natural/fold/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Natural/isZero/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Natural/odd/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Natural/product/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Natural/show/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Natural/sum/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Natural/toDouble/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Natural/toInteger/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Optional/all/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Optional/any/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Optional/build/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Optional/concat/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Optional/filter/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Optional/fold/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Optional/head/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Optional/last/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Optional/length/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Optional/map/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Optional/null/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Optional/toList/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Optional/unzip/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Text/concat/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Text/concatMap/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Text/concatMapSep/*.dhall-    dhall-lang/tests/type-inference/success/prelude/Text/concatSep/*.dhall-    dhall-lang/tests/type-inference/success/regression/*.dhall-    dhall-lang/tests/type-inference/success/simple/*.dhall-    dhall-lang/tests/type-inference/success/simple/access/*.dhall-    dhall-lang/tests/type-inference/success/unit/*.dhall-    tests/diff/*.dhall-    tests/diff/*.txt-    tests/format/*.dhall-    tests/freeze/*.dhall-    tests/lint/success/*.dhall-    tests/recursive/*.dhall-    tests/regression/*.dhall-    tests/schemas/*.dhall-    tests/tags/*.dhall-    tests/tags/*.tags-    tests/th/*.dhall-    tests/tutorial/*.dhall+    tests/**/*.dhall+    tests/**/*.tags+    tests/**/*.txt  Source-Repository head     Type: git@@ -466,62 +198,85 @@   Default:     False   Manual:      True -Library-    Hs-Source-Dirs: src+Flag network-tests+  Description: Enable tests which depend on an internet connection+  Default:     True+  Manual:      True++Common common     Build-Depends:         base                        >= 4.11.0.0 && < 5   ,-        aeson                       >= 1.0.0.0  && < 1.6 ,+        aeson                       >= 1.0.0.0  && < 2.3 ,         aeson-pretty                               < 0.9 ,-        ansi-terminal               >= 0.6.3.1  && < 0.12,+        ansi-terminal               >= 0.6.3.1  && < 1.2 ,         atomic-write                >= 0.2.0.7  && < 0.3 ,-        bytestring                                 < 0.11,+        base16-bytestring           >= 1.0.0.0           ,+        bytestring                                 < 0.13,         case-insensitive                           < 1.3 ,         cborg                       >= 0.2.0.0  && < 0.3 ,         cborg-json                  >= 0.2.2.0  && < 0.3 ,-        containers                  >= 0.5.8.0  && < 0.7 ,+        containers                  >= 0.5.8.0  && < 0.9 ,         contravariant                              < 1.6 ,         data-fix                                   < 0.4 ,-        deepseq                                    < 1.5 ,-        Diff                        >= 0.2      && < 0.5 ,+        deepseq                                    < 1.6 ,+        Diff                        >= 0.2      && < 1.1 ,         directory                   >= 1.3.0.0  && < 1.4 ,         dotgen                      >= 0.4.2    && < 0.5 ,         either                      >= 5        && < 5.1,         exceptions                  >= 0.8.3    && < 0.11,-        filepath                    >= 1.4      && < 1.5 ,+        filepath                    >= 1.4      && < 1.6 ,         half                        >= 0.2.2.3  && < 0.4 ,         haskeline                   >= 0.7.2.1  && < 0.9 ,-        hashable                    >= 1.2      && < 1.4 ,-        lens-family-core            >= 1.0.0    && < 2.2 ,-        megaparsec                  >= 7        && < 9.1 ,-        memory                      >= 0.14     && < 0.16,-        mmorph                                     < 1.2 ,-        mtl                         >= 2.2.1    && < 2.3 ,+        hashable                    >= 1.2      && < 1.6 ,+        indexed-traversable                        < 0.2 ,+        microlens                   >= 0.4.14.0 && < 0.5 ,+        microlens-mtl               >= 0.1      && < 0.3 ,+        -- megaparsec follows SemVer: https://github.com/mrkkrp/megaparsec/issues/469#issuecomment-927918469+        megaparsec                  >= 8        && < 10  ,+        mmorph                                     < 1.3 ,+        mtl                         >= 2.2.1    && < 2.4 ,         network-uri                 >= 2.6      && < 2.7 ,-        optparse-applicative        >= 0.14.0.0 && < 0.17,+        optparse-applicative        >= 0.14.0.0 && < 0.20,         parsers                     >= 0.12.4   && < 0.13,         parser-combinators                               ,-        prettyprinter               >= 1.5.1    && < 1.8 ,-        prettyprinter-ansi-terminal >= 1.1.1    && < 1.2 ,-        pretty-simple                              < 4.1 ,-        profunctors                 >= 3.1.2    && < 5.7 ,+        prettyprinter               >= 1.7.0    && < 1.8 ,+        prettyprinter-ansi-terminal >= 1.1.2    && < 1.2 ,+        pretty-simple                              < 4.2 ,         repline                     >= 0.4.0.0  && < 0.5 ,         serialise                   >= 0.2.0.0  && < 0.3 ,         scientific                  >= 0.3.0.0  && < 0.4 ,-        template-haskell            >= 2.13.0.0 && < 2.17,-        text                        >= 0.11.1.0 && < 1.3 ,-        text-manipulate             >= 0.2.0.1  && < 0.3 ,+        template-haskell            >= 2.13.0.0 && < 2.24,+        text                        >= 0.11.1.0 && < 2.2 ,+        text-manipulate             >= 0.2.0.1  && < 0.4 ,+        text-short                  >= 0.1      && < 0.2 ,         th-lift-instances           >= 0.1.13   && < 0.2 ,-        transformers                >= 0.2.0.0  && < 0.6 ,-        transformers-compat         >= 0.6.2    && < 0.7 ,+        time                        >= 1.9      && < 1.15,+        transformers                >= 0.5.2.0  && < 0.7 ,+        unix-compat                 >= 0.4.2    && < 0.8 ,         unordered-containers        >= 0.1.3.0  && < 0.3 ,-        uri-encode                                 < 1.6 ,-        vector                      >= 0.11.0.0 && < 0.13+        vector                      >= 0.11.0.0 && < 0.14++    if !os(windows)+      Build-Depends:+        unix                        >= 2.7      && < 2.9 ,+     if flag(with-http)       CPP-Options:         -DWITH_HTTP       if flag(use-http-client-tls)         CPP-Options:           -DUSE_HTTP_CLIENT_TLS+      if flag(network-tests)+        CPP-Options:+          -DNETWORK_TESTS+    if flag(cross)+      CPP-Options: -DCROSS++    GHC-Options: -Wall -Wcompat -Wincomplete-uni-patterns -optP-Wno-unicode-homoglyph++Library+    Import: common+    Hs-Source-Dirs: src     if impl(ghcjs)       Hs-Source-Dirs: ghcjs-src       Build-Depends:@@ -530,7 +285,7 @@     else       Hs-Source-Dirs: ghc-src       Build-Depends:-        cryptonite                  >= 0.23     && < 1.0+        cryptohash-sha256       if flag(with-http)         Build-Depends:           http-types                  >= 0.7.0    && < 0.13,@@ -580,8 +335,11 @@         Dhall.Import         Dhall.Lint         Dhall.Main+        Dhall.Marshal.Decode+        Dhall.Marshal.Encode         Dhall.Map         Dhall.Optics+        Dhall.Package         Dhall.Parser         Dhall.Parser.Expression         Dhall.Parser.Token@@ -603,12 +361,39 @@         Exposed-Modules:           Dhall.Deriving     Other-Modules:+        Dhall.DirectoryTree.Types         Dhall.Eval         Dhall.Import.Types+        Dhall.Import.Headers+        Dhall.Marshal.Internal         Dhall.Normalize         Dhall.Parser.Combinators         Dhall.Pretty.Internal         Dhall.Syntax+        Dhall.Syntax.Binding+        Dhall.Syntax.Chunks+        Dhall.Syntax.Const+        Dhall.Syntax.Expr+        Dhall.Syntax.FunctionBinding+        Dhall.Syntax.Import+        Dhall.Syntax.Instances.Applicative+        Dhall.Syntax.Instances.Bifunctor+        Dhall.Syntax.Instances.Data+        Dhall.Syntax.Instances.Eq+        Dhall.Syntax.Instances.Foldable+        Dhall.Syntax.Instances.Functor+        Dhall.Syntax.Instances.Lift+        Dhall.Syntax.Instances.Monad+        Dhall.Syntax.Instances.NFData+        Dhall.Syntax.Instances.Ord+        Dhall.Syntax.Instances.Pretty+        Dhall.Syntax.Instances.Show+        Dhall.Syntax.Instances.Traversable+        Dhall.Syntax.MultiLet+        Dhall.Syntax.Operations+        Dhall.Syntax.RecordField+        Dhall.Syntax.Types+        Dhall.Syntax.Var         Dhall.URL         Paths_dhall     Autogen-Modules:@@ -618,118 +403,95 @@         Dhall.Import.HTTP         Dhall.Import.Manager -    GHC-Options: -Wall -fwarn-incomplete-uni-patterns     Default-Language: Haskell2010  Executable dhall+    Import: common     Hs-Source-Dirs: dhall     Main-Is: Main.hs-    Build-Depends: base, dhall-    GHC-Options: -Wall -rtsopts+    Build-Depends: dhall+    GHC-Options: -rtsopts     Default-Language: Haskell2010  Test-Suite tasty+    Import: common     Type: exitcode-stdio-1.0     Hs-Source-Dirs: tests     Main-Is: Dhall/Test/Main.hs-    GHC-Options: -Wall     Other-Modules:         Dhall.Test.Dhall         Dhall.Test.Diff+        Dhall.Test.DirectoryTree         Dhall.Test.Tags         Dhall.Test.Format         Dhall.Test.Freeze         Dhall.Test.Import         Dhall.Test.Lint         Dhall.Test.Normalization+        Dhall.Test.Package         Dhall.Test.Parser         Dhall.Test.QuickCheck         Dhall.Test.Regression         Dhall.Test.Schemas         Dhall.Test.SemanticHash         Dhall.Test.Substitution-        Dhall.Test.TH         Dhall.Test.Tutorial         Dhall.Test.TypeInference         Dhall.Test.Util+    if !flag(cross)+        Other-Modules:+            Dhall.Test.TH     Build-Depends:-        base                      >= 4        && < 5   ,-        bytestring                               < 0.11,-        cborg                     >= 0.2.0.0  && < 0.3 ,-        containers                                     ,-        data-fix                                       ,-        deepseq                   >= 1.2.0.1  && < 1.5 ,         dhall                                          ,-        directory                                      ,-        either                                         ,-        filepath                                       ,         foldl                                    < 1.5 ,-        generic-random            >= 1.3.0.0  && < 1.4 ,+        generic-random            >= 1.3.0.0  && < 1.6 ,         http-client                                    ,         http-client-tls                                ,-        lens-family-core                               ,-        megaparsec                                     ,-        prettyprinter                                  ,-        QuickCheck                >= 2.10     && < 2.15,+        QuickCheck                >= 2.14     && < 2.17,         quickcheck-instances      >= 0.3.12   && < 0.4 ,-        scientific                                     ,-        serialise                                      ,         special-values                           < 0.2 ,         spoon                                    < 0.4 ,-        tasty                     >= 0.11.2   && < 1.4 ,+        tasty                     >= 0.11.2   && < 1.6 ,         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                                   ,-        turtle                                   < 1.6 ,-        unordered-containers                           ,-        vector                    >= 0.11.0.0 && < 0.13-    if flag(with-http)-      CPP-Options:-        -DWITH_HTTP+        tasty-quickcheck          >= 0.9.2    && < 0.12,+        tasty-silver                             < 3.4 ,+        temporary                 >= 1.2.1    && < 1.4 ,+        turtle                    >= 1.6      && < 1.7 ,     Default-Language: Haskell2010  Test-Suite doctest+    Import: common     Type: exitcode-stdio-1.0     Hs-Source-Dirs: doctest     Main-Is: Main.hs-    GHC-Options: -Wall     Build-Depends:-        base                          ,-        directory                     ,-        filepath                < 1.5 ,         mockery                 < 0.4 ,-        doctest   >= 0.7.0   && < 0.18+        doctest   >= 0.7.0+    if os(windows)+      -- https://github.com/dhall-lang/dhall-haskell/issues/2237+      Buildable: False     Default-Language: Haskell2010  Benchmark dhall-parser+    Import: common     Type: exitcode-stdio-1.0     Hs-Source-Dirs: benchmark/parser     Main-Is: Main.hs     Build-Depends:-        base                      >= 4        && < 5  ,-        bytestring                                    ,-        containers                >= 0.5.0.0  && < 0.7,         dhall                                         ,-        directory                                     ,-        gauge                     >= 0.2.3    && < 0.3,-        text                      >= 0.11.1.0 && < 1.3+        tasty-bench               >= 0.4      && < 0.5,     Default-Language: Haskell2010     Other-Extensions:         TypeApplications-    ghc-options: -rtsopts -Wall+    Ghc-Options: -rtsopts  Benchmark deep-nested-large-record+    Import: common     Type: exitcode-stdio-1.0     Hs-Source-Dirs: benchmark/deep-nested-large-record     Main-Is: Main.hs     Build-Depends:-        base                      >= 4        && < 5  ,-        containers                >= 0.5.0.0  && < 0.7,         dhall                                         ,-        gauge                     >= 0.2.3    && < 0.3+        tasty-bench               >= 0.4      && < 0.5,     Default-Language: Haskell2010-    ghc-options: -Wall
doctest/Main.hs view
@@ -1,22 +1,26 @@ {-# LANGUAGE CPP #-} -module Main where+module Main (main) where  import System.FilePath ((</>))  import qualified GHC.IO.Encoding import qualified System.Directory+import qualified System.Environment import qualified System.IO import qualified Test.DocTest import qualified Test.Mockery.Directory  main :: IO () main = do-     GHC.IO.Encoding.setLocaleEncoding System.IO.utf8-    pwd    <- System.Directory.getCurrentDirectory+    args <- System.Environment.getArgs+    pwd <- System.Directory.getCurrentDirectory     prefix <- System.Directory.makeAbsolute pwd+    let src = prefix </> "src" +    System.Environment.setEnv "XDG_CACHE_HOME" (pwd </> ".cache")+     Test.Mockery.Directory.inTempDirectory $ do         writeFile "makeBools.dhall" "λ(n : Bool) → [ n && True, n && False, n || True, n || False ]"         writeFile "bool1" "True"@@ -31,11 +35,12 @@           , "in  { name = \"Simon\", favoriteFont = Font.`Comic Sans` } : Person"           ] -        Test.DocTest.doctest+        Test.DocTest.doctest $             [ "-DWITH_HTTP"             , "-DUSE_HTTP_CLIENT_TLS"             , "--fast"-            , prefix </> "ghc-src"+            ] <> args <>+            [ prefix </> "ghc-src"              -- Unfortunately we cannot target the entire @src@ directory.             -- The reason is that src/Dhall/Version.hs depends on@@ -44,11 +49,11 @@             -- Instead, we target a selection of modules whose combined module             -- dependency tree covers all modules that contain doctests. -            -- , prefix </> "src"-            , "-i" <> (prefix </> "src")+            -- , src+            , "-i" <> src #if __GLASGOW_HASKELL__ >= 806-            , prefix </> "src/Dhall/Deriving.hs"+            , src </> "Dhall/Deriving.hs" #endif-            , prefix </> "src/Dhall/Tags.hs"-            , prefix </> "src/Dhall/Tutorial.hs"+            , src </> "Dhall/Tags.hs"+            , src </> "Dhall/Tutorial.hs"             ]
ghc-src/Dhall/Crypto.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE DeriveDataTypeable         #-} {-# LANGUAGE DeriveGeneric              #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} @@ -13,18 +14,18 @@     ) where  import Control.DeepSeq         (NFData)-import Crypto.Hash             (SHA256)-import Data.ByteArray          (ByteArrayAccess, convert)-import Data.ByteArray.Encoding (Base (Base16), convertToBase) import Data.ByteString         (ByteString)+import Data.Data               (Data) import GHC.Generics            (Generic) -import qualified Crypto.Hash-import qualified Data.ByteString.Char8 as ByteString.Char8+import qualified Crypto.Hash.SHA256+import qualified Data.ByteString        as ByteString+import qualified Data.ByteString.Base16 as Base16+import qualified Data.ByteString.Char8  as ByteString.Char8  -- | A SHA256 digest newtype SHA256Digest = SHA256Digest { unSHA256Digest :: ByteString }-  deriving (Eq, Generic, Ord, NFData, ByteArrayAccess)+  deriving (Data, Eq, Generic, Ord, NFData)  instance Show SHA256Digest where   show = toString@@ -33,16 +34,14 @@     `Nothing` if the conversion fails -} sha256DigestFromByteString :: ByteString -> Maybe SHA256Digest-sha256DigestFromByteString bytes = SHA256Digest . convert <$> mh-  where-    mh = Crypto.Hash.digestFromByteString bytes :: Maybe (Crypto.Hash.Digest SHA256)+sha256DigestFromByteString bytes+  | ByteString.length bytes == 32 = Just (SHA256Digest bytes)+  | otherwise                     = Nothing  -- | Hash a `ByteString` and return the hash as a `SHA256Digest` sha256Hash :: ByteString -> SHA256Digest-sha256Hash bytes = SHA256Digest $ convert h-  where-    h = Crypto.Hash.hash bytes :: Crypto.Hash.Digest SHA256+sha256Hash = SHA256Digest . Crypto.Hash.SHA256.hash  -- | 'String' representation of a 'SHA256Digest' toString :: SHA256Digest -> String-toString (SHA256Digest bytes) = ByteString.Char8.unpack $ convertToBase Base16 bytes+toString (SHA256Digest bytes) = ByteString.Char8.unpack $ Base16.encode bytes
ghc-src/Dhall/Import/HTTP.hs view
@@ -1,8 +1,11 @@+{-# LANGUAGE NamedFieldPuns    #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards   #-}  module Dhall.Import.HTTP     ( fetchFromHttpUrl+    , fetchFromHttpUrlBytes+    , originHeadersFileExpr     ) where  import Control.Exception                (Exception)@@ -11,29 +14,35 @@ import Data.ByteString                  (ByteString) import Data.CaseInsensitive             (CI) import Data.Dynamic                     (toDyn)+import Data.List.NonEmpty               (NonEmpty (..))+import Data.Text.Encoding               (decodeUtf8) import Dhall.Core-    ( Import (..)+    ( Expr (..)+    , Directory (..)+    , File (..)+    , FilePrefix (..)+    , Import (..)     , ImportHashed (..)+    , ImportMode (..)     , ImportType (..)     , Scheme (..)     , URL (..)     ) import Dhall.Import.Types+import Dhall.Parser                     (Src) import Dhall.URL                        (renderURL)+import System.Directory                 (getXdgDirectory, XdgDirectory(XdgConfig))+import System.FilePath                  (splitDirectories)  -import Network.HTTP.Client-    ( HttpException (..)-    , HttpExceptionContent (..)-    )+import Network.HTTP.Client (HttpException (..), HttpExceptionContent (..))  import qualified Control.Exception import qualified Control.Monad.Trans.State.Strict as State-import qualified Data.List.NonEmpty               as NonEmpty+import qualified Data.ByteString.Lazy             as ByteString.Lazy+import qualified Data.HashMap.Strict              as HashMap import qualified Data.Text                        as Text import qualified Data.Text.Encoding-import qualified Data.Text.Lazy-import qualified Data.Text.Lazy.Encoding import qualified Dhall.Util import qualified Network.HTTP.Client              as HTTP import qualified Network.HTTP.Types@@ -65,6 +74,11 @@       <>  "\ESC[1;31mError\ESC[0m: The remote host took too long to respond\n"       <>  "\n"       <>  "URL: " <> url <> "\n"+    ConnectionTimeout ->+          "\n"+      <>  "\ESC[1;31mError\ESC[0m: Connection establishment took too long\n"+      <>  "\n"+      <>  "URL: " <> url <> "\n"     StatusCodeException response body -> prefix <> suffix       where         prefix@@ -141,7 +155,10 @@                      prefixedText = Text.unlines prefixedLines -    e' -> "\n" <> show e' <> "\n"+    e' -> "\n"+      <>  "\ESC[1;31mError\ESC[0m: " <> show e'+      <>  "\n"+      <>  "URL: " <> url <> "\n"  newManager :: StateT Status IO Manager newManager = do@@ -233,20 +250,36 @@                 Control.Exception.throwIO (NotCORSCompliant {..}) corsCompliant _ _ _ = return () -type HTTPHeader = Network.HTTP.Types.Header+addHeaders :: OriginHeaders -> Maybe [HTTPHeader] -> HTTP.Request -> HTTP.Request+addHeaders originHeaders urlHeaders request =+    request { HTTP.requestHeaders = (filterHeaders urlHeaders) <> perOriginHeaders }+      where+        origin = decodeUtf8 (HTTP.host request) <> ":" <> Text.pack (show (HTTP.port request))+ +        perOriginHeaders = HashMap.lookupDefault [] origin originHeaders -fetchFromHttpUrl :: URL -> Maybe [HTTPHeader] -> StateT Status IO Text.Text-fetchFromHttpUrl childURL mheaders = do+        filterHeaders = foldMap (filter (not . overridden))++        overridden :: HTTPHeader -> Bool+        overridden (key, _value) = any (matchesKey key) perOriginHeaders++        matchesKey :: CI ByteString -> HTTPHeader -> Bool+        matchesKey key (candidate, _value) = key == candidate++fetchFromHttpUrlBytes+    :: URL -> Maybe [HTTPHeader] -> StateT Status IO ByteString+fetchFromHttpUrlBytes childURL mheaders = do+    Status { _loadOriginHeaders } <- State.get++    originHeaders <- _loadOriginHeaders+     manager <- newManager      let childURLString = Text.unpack (renderURL childURL) -    request <- liftIO (HTTP.parseUrlThrow childURLString)+    baseRequest <- liftIO (HTTP.parseUrlThrow childURLString) -    let requestWithHeaders =-            case mheaders of-              Nothing      -> request-              Just headers -> request { HTTP.requestHeaders = headers }+    let requestWithHeaders = addHeaders originHeaders mheaders baseRequest      let io = HTTP.httpLbs requestWithHeaders manager @@ -258,14 +291,30 @@      Status {..} <- State.get -    let Chained parentImport = NonEmpty.head _stack+    case _stack of+        -- We ignore the first import in the stack since that is the same import+        -- as the `childUrl`+        _ :| Chained parentImport : _ -> do+            let parentImportType = importType (importHashed parentImport) -    let parentImportType = importType (importHashed parentImport)+            corsCompliant parentImportType childURL (HTTP.responseHeaders response)+        _ -> do+            return () -    corsCompliant parentImportType childURL (HTTP.responseHeaders response)+    return (ByteString.Lazy.toStrict (HTTP.responseBody response)) -    let bytes = HTTP.responseBody response+fetchFromHttpUrl :: URL -> Maybe [HTTPHeader] -> StateT Status IO Text.Text+fetchFromHttpUrl childURL mheaders = do+    bytes <- fetchFromHttpUrlBytes childURL mheaders -    case Data.Text.Lazy.Encoding.decodeUtf8' bytes of+    case Data.Text.Encoding.decodeUtf8' bytes of         Left  err  -> liftIO (Control.Exception.throwIO err)-        Right text -> return (Data.Text.Lazy.toStrict text)+        Right text -> return text++originHeadersFileExpr :: IO (Expr Src Import)+originHeadersFileExpr = do+    directoryStr <- getXdgDirectory XdgConfig "dhall"+    let components = map Text.pack (splitDirectories directoryStr)+    let directory = Directory (reverse components)+    let file = (File directory "headers.dhall")+    return (Embed (Import (ImportHashed Nothing (Local Absolute file)) Code))
ghc-src/Dhall/Import/Manager.hs view
@@ -16,7 +16,7 @@     , defaultNewManager     ) where -import Network.HTTP.Client (Manager, newManager)+import           Network.HTTP.Client (Manager, newManager) import qualified Network.HTTP.Client as HTTP  #ifdef USE_HTTP_CLIENT_TLS
ghcjs-src/Dhall/Crypto.hs view
@@ -1,6 +1,7 @@-{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveDataTypeable         #-}+{-# LANGUAGE DeriveGeneric              #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE JavaScriptFFI #-}+{-# LANGUAGE JavaScriptFFI              #-}  {-| This module provides implementations of cryptographic utilities that only     work for GHCJS@@ -12,32 +13,32 @@     , sha256Hash     ) where -import Control.DeepSeq (NFData)-import Data.ByteArray (ByteArrayAccess)-import Data.ByteArray.Encoding (Base(Base16), convertToBase)-import Data.ByteString (ByteString)-import GHC.Generics (Generic)+import Control.DeepSeq                   (NFData)+import Data.ByteString                   (ByteString)+import Data.Data                         (Data)+import GHC.Generics                      (Generic) import JavaScript.TypedArray.ArrayBuffer (ArrayBuffer)-import System.IO.Unsafe (unsafePerformIO)+import System.IO.Unsafe                  (unsafePerformIO)  import qualified Data.ByteString        as ByteString+import qualified Data.ByteString.Base16 as Base16 import qualified Data.ByteString.Char8  as ByteString.Char8 import qualified GHCJS.Buffer           as Buffer  -- | A SHA256 digest newtype SHA256Digest = SHA256Digest { unSHA256Digest :: ByteString }-  deriving (Eq, Generic, Ord, NFData, ByteArrayAccess)+  deriving (Data, Eq, Generic, Ord, NFData)  instance Show SHA256Digest where-  show (SHA256Digest bytes) = ByteString.Char8.unpack $ convertToBase Base16 bytes+  show (SHA256Digest bytes) = ByteString.Char8.unpack $ Base16.encode bytes  {-| Attempt to interpret a `ByteString` as a `SHA256Digest`, returning     `Nothing` if the conversion fails -} sha256DigestFromByteString :: ByteString -> Maybe SHA256Digest sha256DigestFromByteString bytes-  | ByteString.length bytes == 32 = Just $ SHA256Digest bytes-  | otherwise = Nothing+  | ByteString.length bytes == 32 = Just (SHA256Digest bytes)+  | otherwise                     = Nothing  -- Use NodeJS' crypto module if there's a 'process' module, e.g. we're running -- inside GHCJS' THRunner. If we're running in the browser, use the WebCrypto
ghcjs-src/Dhall/Import/HTTP.hs view
@@ -2,17 +2,21 @@  module Dhall.Import.HTTP     ( fetchFromHttpUrl+    , fetchFromHttpUrlBytes+    , originHeadersFileExpr     ) where  import Control.Monad.IO.Class           (MonadIO (..)) import Control.Monad.Trans.State.Strict (StateT) import Data.ByteString                  (ByteString) import Data.CaseInsensitive             (CI)-import Dhall.Core                       (URL (..))-import Dhall.Import.Types               (Status)+import Dhall.Core                       (URL (..), Expr (..))+import Dhall.Import.Types               (Import, Status)+import Dhall.Parser                     (Src) import Dhall.URL                        (renderURL) -import qualified Data.Text      as Text+import qualified Data.Text          as Text+import qualified Data.Text.Encoding as Text.Encoding import qualified JavaScript.XHR  fetchFromHttpUrl@@ -35,3 +39,14 @@     return body fetchFromHttpUrl _ _ =     fail "Dhall does not yet support custom headers when built using GHCJS"++fetchFromHTTPUrlBytes+    :: URL+    -> Maybe [(CI ByteString, ByteString)]+    -> StateT Status IO ByteString+fetchFromHTTPUrlBytes childUrl mheader = do+    text <- fetchFromHTTPUrl childUrl mheader+    return (Text.Encoding.encodeUtf8 text)++originHeadersFileExpr :: IO (Expr Src Import)+originHeadersFileExpr = return Missing
man/dhall.1 view
@@ -97,4 +97,4 @@ .SH BUGS .PP Please report any bugs you may come across to-https://github.com/dhall-language/dhall-haskell/issues.+https://github.com/dhall-lang/dhall-haskell/issues.
src/Dhall.hs view
@@ -1,2893 +1,579 @@-{-# LANGUAGE ApplicativeDo              #-}-{-# LANGUAGE ConstraintKinds            #-}-{-# LANGUAGE DefaultSignatures          #-}-{-# LANGUAGE DeriveFunctor              #-}-{-# LANGUAGE FlexibleContexts           #-}-{-# LANGUAGE FlexibleInstances          #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE MultiParamTypeClasses      #-}-{-# LANGUAGE MultiWayIf                 #-}-{-# LANGUAGE OverloadedStrings          #-}-{-# LANGUAGE PolyKinds                  #-}-{-# LANGUAGE RankNTypes                 #-}-{-# 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--}--module Dhall-    (-    -- * Input-      input-    , inputWithSettings-    , inputFile-    , inputFileWithSettings-    , inputExpr-    , inputExprWithSettings-    , rootDirectory-    , sourceName-    , startingContext-    , substitutions-    , normalizer-    , newManager-    , defaultInputSettings-    , InputSettings-    , defaultEvaluateSettings-    , EvaluateSettings-    , HasEvaluateSettings(..)-    , detailed--    -- * Decoders-    , Decoder (..)-    , RecordDecoder(..)-    , UnionDecoder(..)-    , Encoder(..)-    , FromDhall(..)-    , Interpret-    , InvalidDecoder(..)-    , ExtractErrors-    , ExtractError(..)-    , Extractor-    , MonadicExtractor-    , typeError-    , extractError-    , toMonadic-    , fromMonadic-    , ExpectedTypeErrors-    , ExpectedTypeError(..)-    , Expector-    , auto-    , genericAuto-    , genericAutoWith-    , InterpretOptions(..)-    , InputNormalizer(..)-    , defaultInputNormalizer-    , SingletonConstructors(..)-    , defaultInterpretOptions-    , bool-    , natural-    , integer-    , word-    , word8-    , word16-    , word32-    , word64-    , int-    , int8-    , int16-    , int32-    , int64-    , scientific-    , double-    , lazyText-    , strictText-    , maybe-    , sequence-    , list-    , vector-    , function-    , functionWith-    , setFromDistinctList-    , setIgnoringDuplicates-    , hashSetFromDistinctList-    , hashSetIgnoringDuplicates-    , Dhall.map-    , hashMap-    , pairFromMapEntry-    , unit-    , void-    , string-    , pair-    , record-    , field-    , union-    , constructor-    , GenericFromDhall(..)-    , GenericFromDhallUnion(..)-    , ToDhall(..)-    , Inject-    , inject-    , genericToDhall-    , genericToDhallWith-    , RecordEncoder(..)-    , encodeFieldWith-    , encodeField-    , recordEncoder-    , UnionEncoder(..)-    , encodeConstructorWith-    , encodeConstructor-    , unionEncoder-    , (>|<)-    , GenericToDhall(..)--    -- * Miscellaneous-    , DhallErrors(..)-    , showDhallErrors-    , rawInput-    , (>$<)-    , (>*<)-    , Result--    -- * Re-exports-    , Natural-    , Seq-    , Text-    , Vector-    , Generic-    ) where--import Control.Applicative                  (Alternative, empty, liftA2)-import Control.Exception                    (Exception)-import Control.Monad                        (guard)-import Control.Monad.Trans.State.Strict-import Data.Coerce                          (coerce)-import Data.Either.Validation-    ( Validation (..)-    , eitherToValidation-    , validationToEither-    )-import Data.Fix                             (Fix (..))-import Data.Functor.Contravariant           (Contravariant (..), Op (..), (>$<))-import Data.Functor.Contravariant.Divisible (Divisible (..), divided)-import Data.Hashable                        (Hashable)-import Data.HashMap.Strict                  (HashMap)-import Data.List.NonEmpty                   (NonEmpty (..))-import Data.Map                             (Map)-import Data.Scientific                      (Scientific)-import Data.Sequence                        (Seq)-import Data.Text                            (Text)-import Data.Text.Prettyprint.Doc            (Pretty)-import Data.Typeable                        (Proxy (..), Typeable)-import Data.Vector                          (Vector)-import Data.Void                            (Void)-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 (..)-    )-import Dhall.TypeCheck                      (DetailedTypeError (..), TypeError)-import GHC.Generics-import Lens.Family                          (LensLike', view)-import Numeric.Natural                      (Natural)-import Prelude                              hiding (maybe, sequence)-import System.FilePath                      (takeDirectory)--import qualified Control.Applicative-import qualified Control.Exception-import qualified Control.Monad.Trans.State.Strict as State-import qualified Data.Foldable-import qualified Data.Functor.Compose-import qualified Data.Functor.Product-import qualified Data.HashMap.Strict              as HashMap-import qualified Data.HashSet-import qualified Data.List-import qualified Data.List.NonEmpty-import qualified Data.Map-import qualified Data.Maybe-import qualified Data.Scientific-import qualified Data.Sequence-import qualified Data.Set-import qualified Data.Text-import qualified Data.Text.IO-import qualified Data.Text.Lazy-import qualified Data.Vector-import qualified Data.Void-import qualified Dhall.Context-import qualified Dhall.Core                       as Core-import qualified Dhall.Import-import qualified Dhall.Map-import qualified Dhall.Parser-import qualified Dhall.Pretty.Internal-import qualified Dhall.Substitution-import qualified Dhall.TypeCheck-import qualified Dhall.Util-import qualified Lens.Family---- $setup--- >>> :set -XOverloadedStrings--- >>> :set -XRecordWildCards--- >>> import Data.Word (Word8, Word16, Word32, Word64)--- >>> import Dhall.Pretty.Internal (prettyExpr)--{-| A newtype suitable for collecting one or more errors--}-newtype DhallErrors e = DhallErrors-   { getErrors :: NonEmpty e-   } deriving (Eq, Functor, Semigroup)--instance (Show (DhallErrors e), Typeable e) => Exception (DhallErrors e)--{-| Render a given prefix and some errors to a string.--}-showDhallErrors :: Show e => String -> DhallErrors e -> String-showDhallErrors _   (DhallErrors (e :| [])) = show e-showDhallErrors ctx (DhallErrors es) = prefix <> (unlines . Data.List.NonEmpty.toList . fmap show $ es)-  where-    prefix =-        "Multiple errors were encountered" ++ ctx ++ ": \n\-        \                                               \n"--{-| Useful synonym for the `Validation` type used when marshalling Dhall-    expressions--}-type Extractor s a = Validation (ExtractErrors s a)--{-| Useful synonym for the equivalent `Either` type used when marshalling Dhall-    code--}-type MonadicExtractor s a = Either (ExtractErrors s a)--{-| Generate a type error during extraction by specifying the expected type-    and the actual type.-    The expected type is not yet determined.--}-typeError :: Expector (Expr s a) -> Expr s a -> Extractor s a b-typeError expected actual = Failure $ case expected of-    Failure e         -> fmap ExpectedTypeError e-    Success expected' -> DhallErrors $ pure $ TypeMismatch $ InvalidDecoder expected' actual---- | Turn a `Data.Text.Text` message into an extraction failure-extractError :: Text -> Extractor s a b-extractError = Failure . DhallErrors . pure . ExtractError--{-| Useful synonym for the `Validation` type used when marshalling Dhall-    expressions--}-type Expector = Validation ExpectedTypeErrors--{-| One or more errors returned when determining the Dhall type of a-    Haskell expression--}-type ExpectedTypeErrors = DhallErrors ExpectedTypeError--{-| Error type used when determining the Dhall type of a Haskell expression--}-data ExpectedTypeError = RecursiveTypeError-    deriving (Eq, Show)--instance Exception ExpectedTypeError--instance Show ExpectedTypeErrors where-    show = showDhallErrors " while determining the expected type"---- | Switches from an @Applicative@ extraction result, able to accumulate errors,--- to a @Monad@ extraction result, able to chain sequential operations-toMonadic :: Extractor s a b -> MonadicExtractor s a b-toMonadic = validationToEither---- | Switches from a @Monad@ extraction result, able to chain sequential errors,--- to an @Applicative@ extraction result, able to accumulate errors-fromMonadic :: MonadicExtractor s a b -> Extractor s a b-fromMonadic = eitherToValidation--{-| One or more errors returned from extracting a Dhall expression to a-    Haskell expression--}-type ExtractErrors s a = DhallErrors (ExtractError s a)--instance (Pretty s, Pretty a, Typeable s, Typeable a) => Show (ExtractErrors s a) where-    show = showDhallErrors " during extraction"--{-| Extraction of a value can fail for two reasons, either a type mismatch (which should not happen,-    as expressions are type-checked against the expected type before being passed to @extract@), or-    a term-level error, described with a freeform text value.--}-data ExtractError s a =-    TypeMismatch (InvalidDecoder s a)-  | ExpectedTypeError ExpectedTypeError-  | ExtractError Text--instance (Pretty s, Pretty a, Typeable s, Typeable a) => Show (ExtractError s a) where-  show (TypeMismatch e)      = show e-  show (ExpectedTypeError e) = show e-  show (ExtractError es)     =-      _ERROR <> ": Failed extraction                                                   \n\-      \                                                                                \n\-      \The expression type-checked successfully but the transformation to the target   \n\-      \type failed with the following error:                                           \n\-      \                                                                                \n\-      \" <> Data.Text.unpack es <> "\n\-      \                                                                                \n"--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 `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 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-  , invalidDecoderExpression :: Expr s a-  }-  deriving (Typeable)--instance (Pretty s, Typeable s, Pretty a, Typeable a) => Exception (InvalidDecoder s a)--_ERROR :: String-_ERROR = "\ESC[1;31mError\ESC[0m"--instance (Pretty s, Pretty a, Typeable s, Typeable a) => Show (InvalidDecoder s a) where-    show InvalidDecoder { .. } =-        _ERROR <> ": Invalid Dhall.Decoder                                               \n\-        \                                                                                \n\-        \Every Decoder must provide an extract function that succeeds if an expression   \n\-        \matches the expected type.  You provided a Decoder that disobeys this contract  \n\-        \                                                                                \n\-        \The Decoder provided has the expected dhall type:                               \n\-        \                                                                                \n\-        \" <> show txt0 <> "\n\-        \                                                                                \n\-        \and it couldn't extract a value from the well-typed expression:                 \n\-        \                                                                                \n\-        \" <> show txt1 <> "\n\-        \                                                                                \n"-        where-          txt0 = Dhall.Util.insert invalidDecoderExpected-          txt1 = Dhall.Util.insert invalidDecoderExpression---- | @since 1.16-data InputSettings = InputSettings-  { _rootDirectory :: FilePath-  , _sourceName :: FilePath-  , _evaluateSettings :: EvaluateSettings-  }---- | Default input settings: resolves imports relative to @.@ (the--- current working directory), report errors as coming from @(input)@,--- and default evaluation settings from 'defaultEvaluateSettings'.------ @since 1.16-defaultInputSettings :: InputSettings-defaultInputSettings = InputSettings-  { _rootDirectory = "."-  , _sourceName = "(input)"-  , _evaluateSettings = defaultEvaluateSettings-  }----- | Access the directory to resolve imports relative to.------ @since 1.16-rootDirectory-  :: (Functor f)-  => LensLike' f InputSettings FilePath-rootDirectory k s =-  fmap (\x -> s { _rootDirectory = x }) (k (_rootDirectory s))---- | Access the name of the source to report locations from; this is--- only used in error messages, so it's okay if this is a best guess--- or something symbolic.------ @since 1.16-sourceName-  :: (Functor f)-  => LensLike' f InputSettings FilePath-sourceName k s =-  fmap (\x -> s { _sourceName = x}) (k (_sourceName s))---- | @since 1.16-data EvaluateSettings = EvaluateSettings-  { _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--- context, and no special normalizer behaviour.------ @since 1.16-defaultEvaluateSettings :: EvaluateSettings-defaultEvaluateSettings = EvaluateSettings-  { _substitutions   = Dhall.Substitution.empty-  , _startingContext = Dhall.Context.empty-  , _normalizer      = Nothing-  , _newManager      = Dhall.Import.defaultNewManager-  }---- | Access the starting context used for evaluation and type-checking.------ @since 1.16-startingContext-  :: (Functor f, HasEvaluateSettings s)-  => LensLike' f s (Dhall.Context.Context (Expr Src Void))-startingContext = evaluateSettings . l-  where-    l :: (Functor f)-      => LensLike' f EvaluateSettings (Dhall.Context.Context (Expr Src Void))-    l k s = fmap (\x -> s { _startingContext = x}) (k (_startingContext s))---- | Access the custom substitutions.------ @since 1.30-substitutions-  :: (Functor f, HasEvaluateSettings s)-  => LensLike' f s (Dhall.Substitution.Substitutions Src Void)-substitutions = evaluateSettings . l-  where-    l :: (Functor f)-      => LensLike' f EvaluateSettings (Dhall.Substitution.Substitutions Src Void)-    l k s = fmap (\x -> s { _substitutions = x }) (k (_substitutions s))---- | Access the custom normalizer.------ @since 1.16-normalizer-  :: (Functor f, HasEvaluateSettings s)-  => LensLike' f s (Maybe (Core.ReifiedNormalizer Void))-normalizer = evaluateSettings . l-  where-    l :: (Functor f)-      => 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-    :: (Functor f)-    => LensLike' f s EvaluateSettings--instance HasEvaluateSettings InputSettings where-  evaluateSettings k s =-    fmap (\x -> s { _evaluateSettings = x }) (k (_evaluateSettings s))--instance HasEvaluateSettings EvaluateSettings where-  evaluateSettings = id--{-| Type-check and evaluate a Dhall program, decoding the result into Haskell--    The first argument determines the type of value that you decode:-->>> input integer "+2"-2->>> input (vector double) "[1.0, 2.0]"-[1.0,2.0]--    Use `auto` to automatically select which type to decode based on the-    inferred return type:-->>> input auto "True" :: IO Bool-True--    This uses the settings from 'defaultInputSettings'.--}-input-    :: Decoder a-    -- ^ The decoder for the Dhall value-    -> Text-    -- ^ The Dhall program-    -> IO a-    -- ^ The decoded value in Haskell-input =-  inputWithSettings defaultInputSettings--{-| Extend 'input' with a root directory to resolve imports relative-    to, a file to mention in errors as the source, a custom typing-    context, and a custom normalization process.--@since 1.16--}-inputWithSettings-    :: InputSettings-    -> Decoder a-    -- ^ The decoder for the Dhall value-    -> Text-    -- ^ The Dhall program-    -> IO a-    -- ^ The decoded value in Haskell-inputWithSettings settings (Decoder {..}) txt = do-    expected' <- case expected of-        Success x -> return x-        Failure e -> Control.Exception.throwIO e--    let suffix = Dhall.Pretty.Internal.prettyToStrictText expected'-    let annotate substituted = case substituted of-            Note (Src begin end bytes) _ ->-                Note (Src begin end bytes') (Annot substituted expected')-              where-                bytes' = bytes <> " : " <> suffix-            _ ->-                Annot substituted expected'--    normExpr <- inputHelper annotate settings txt--    case extract normExpr  of-        Success x  -> return x-        Failure e -> Control.Exception.throwIO e--{-| Type-check and evaluate a Dhall program that is read from the-    file-system.--    This uses the settings from 'defaultEvaluateSettings'.--    @since 1.16--}-inputFile-  :: Decoder a-  -- ^ The decoder for the Dhall value-  -> FilePath-  -- ^ The path to the Dhall program.-  -> IO a-  -- ^ The decoded value in Haskell.-inputFile =-  inputFileWithSettings defaultEvaluateSettings--{-| Extend 'inputFile' with a custom typing context and a custom-    normalization process.--@since 1.16--}-inputFileWithSettings-  :: EvaluateSettings-  -> Decoder a-  -- ^ The decoder for the Dhall value-  -> FilePath-  -- ^ The path to the Dhall program.-  -> IO a-  -- ^ The decoded value in Haskell.-inputFileWithSettings settings ty path = do-  text <- Data.Text.IO.readFile path-  let inputSettings = InputSettings-        { _rootDirectory = takeDirectory path-        , _sourceName = path-        , _evaluateSettings = settings-        }-  inputWithSettings inputSettings ty text--{-| Similar to `input`, but without interpreting the Dhall `Expr` into a Haskell-    type.--    Uses the settings from 'defaultInputSettings'.--}-inputExpr-    :: Text-    -- ^ The Dhall program-    -> IO (Expr Src Void)-    -- ^ The fully normalized AST-inputExpr =-  inputExprWithSettings defaultInputSettings--{-| Extend 'inputExpr' with a root directory to resolve imports relative-    to, a file to mention in errors as the source, a custom typing-    context, and a custom normalization process.--@since 1.16--}-inputExprWithSettings-    :: InputSettings-    -> Text-    -- ^ The Dhall program-    -> IO (Expr Src Void)-    -- ^ The fully normalized AST-inputExprWithSettings = inputHelper id--{-| Helper function for the input* function family--@since 1.30--}-inputHelper-    :: (Expr Src Void -> Expr Src Void)-    -> InputSettings-    -> Text-    -- ^ The Dhall program-    -> IO (Expr Src Void)-    -- ^ The fully normalized AST-inputHelper annotate settings txt = do-    expr  <- Core.throws (Dhall.Parser.exprFromText (view sourceName settings) txt)--    let InputSettings {..} = settings--    let EvaluateSettings {..} = _evaluateSettings--    let transform =-               Lens.Family.set Dhall.Import.substitutions   _substitutions-            .  Lens.Family.set Dhall.Import.normalizer      _normalizer-            .  Lens.Family.set Dhall.Import.startingContext _startingContext--    let status = transform (Dhall.Import.emptyStatusWithManager _newManager _rootDirectory)--    expr' <- State.evalStateT (Dhall.Import.loadWith expr) status--    let substituted = Dhall.Substitution.substitute expr' $ view substitutions settings-    let annot = annotate substituted-    _ <- Core.throws (Dhall.TypeCheck.typeWith (view startingContext settings) annot)-    pure (Core.normalizeWith (view normalizer settings) substituted)---- | Use this function to extract Haskell values directly from Dhall AST.---   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---   a much better user experience.-rawInput-    :: Alternative f-    => Decoder a-    -- ^ The decoder for the Dhall value-    -> Expr s Void-    -- ^ a closed form Dhall program, which evaluates to the expected type-    -> f a-    -- ^ The decoded value in Haskell-rawInput (Decoder {..}) expr =-    case extract (Core.normalize expr) of-        Success x  -> pure x-        Failure _e -> empty--{-| Use this to provide more detailed error messages-->> input auto "True" :: IO Integer-> *** Exception: Error: Expression doesn't match annotation->-> True : Integer->-> (input):1:1-->> detailed (input auto "True") :: IO Integer-> *** Exception: Error: Expression doesn't match annotation->-> Explanation: You can annotate an expression with its type or kind using the-> ❰:❱ symbol, like this:->->->     ┌───────┐->     │ x : t │  ❰x❱ is an expression and ❰t❱ is the annotated type or kind of ❰x❱->     └───────┘->-> The type checker verifies that the expression's type or kind matches the-> provided annotation->-> For example, all of the following are valid annotations that the type checker-> accepts:->->->     ┌─────────────┐->     │ 1 : Natural │  ❰1❱ is an expression that has type ❰Natural❱, so the type->     └─────────────┘  checker accepts the annotation->->->     ┌───────────────────────┐->     │ Natural/even 2 : Bool │  ❰Natural/even 2❱ has type ❰Bool❱, so the type->     └───────────────────────┘  checker accepts the annotation->->->     ┌────────────────────┐->     │ List : Type → Type │  ❰List❱ is an expression that has kind ❰Type → Type❱,->     └────────────────────┘  so the type checker accepts the annotation->->->     ┌──────────────────┐->     │ List Text : Type │  ❰List Text❱ is an expression that has kind ❰Type❱, so->     └──────────────────┘  the type checker accepts the annotation->->-> However, the following annotations are not valid and the type checker will-> reject them:->->->     ┌──────────┐->     │ 1 : Text │  The type checker rejects this because ❰1❱ does not have type->     └──────────┘  ❰Text❱->->->     ┌─────────────┐->     │ List : Type │  ❰List❱ does not have kind ❰Type❱->     └─────────────┘->->-> You or the interpreter annotated this expression:->-> ↳ True->-> ... with this type or kind:->-> ↳ Integer->-> ... but the inferred type or kind of the expression is actually:->-> ↳ Bool->-> Some common reasons why you might get this error:->-> ● The Haskell Dhall interpreter implicitly inserts a top-level annotation->   matching the expected type->->   For example, if you run the following Haskell code:->->->     ┌───────────────────────────────┐->     │ >>> input auto "1" :: IO Text │->     └───────────────────────────────┘->->->   ... then the interpreter will actually type check the following annotated->   expression:->->->     ┌──────────┐->     │ 1 : Text │->     └──────────┘->->->   ... and then type-checking will fail->-> ────────────────────────────────────────────────────────────────────────────────->-> True : Integer->-> (input):1:1---}-detailed :: IO a -> IO a-detailed =-    Control.Exception.handle handler1 . Control.Exception.handle handler0-  where-    handler0 :: Imported (TypeError Src Void) -> IO a-    handler0 (Imported ps e) =-        Control.Exception.throwIO (Imported ps (DetailedTypeError e))--    handler1 :: TypeError Src Void -> IO a-    handler1 e = Control.Exception.throwIO (DetailedTypeError e)--{-| A @(Decoder a)@ represents a way to marshal a value of type @\'a\'@ from Dhall-    into Haskell--    You can produce `Decoder`s either explicitly:--> example :: Decoder (Vector Text)-> example = vector text--    ... or implicitly using `auto`:--> example :: Decoder (Vector Text)-> example = auto--    You can consume `Decoder`s using the `input` function:--> input :: Decoder a -> Text -> IO a--}-data Decoder a = Decoder-    { extract  :: Expr Src Void -> Extractor Src Void a-    -- ^ Extracts Haskell value from the Dhall expression-    , expected :: Expector (Expr Src Void)-    -- ^ Dhall type of the Haskell value-    }-    deriving (Functor)--{-| Decode a `Prelude.Bool`-->>> input bool "True"-True--}-bool :: Decoder Bool-bool = Decoder {..}-  where-    extract (BoolLit b) = pure b-    extract expr        = typeError expected expr--    expected = pure Bool--{-| Decode a `Prelude.Natural`-->>> input natural "42"-42--}-natural :: Decoder Natural-natural = Decoder {..}-  where-    extract (NaturalLit n) = pure n-    extract  expr          = typeError expected expr--    expected = pure Natural--{-| Decode an `Prelude.Integer`-->>> input integer "+42"-42--}-integer :: Decoder Integer-integer = Decoder {..}-  where-    extract (IntegerLit n) = pure n-    extract  expr          = typeError expected expr--    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--}-scientific :: Decoder Scientific-scientific = fmap Data.Scientific.fromFloatDigits double--{-| Decode a `Prelude.Double`-->>> input double "42.0"-42.0--}-double :: Decoder Double-double = Decoder {..}-  where-    extract (DoubleLit (DhallDouble n)) = pure n-    extract  expr                       = typeError expected expr--    expected = pure Double--{-| Decode lazy `Data.Text.Text`-->>> input lazyText "\"Test\""-"Test"--}-lazyText :: Decoder Data.Text.Lazy.Text-lazyText = fmap Data.Text.Lazy.fromStrict strictText--{-| Decode strict `Data.Text.Text`-->>> input strictText "\"Test\""-"Test"--}-strictText :: Decoder Text-strictText = Decoder {..}-  where-    extract (TextLit (Chunks [] t)) = pure t-    extract  expr                   = typeError expected expr--    expected = pure Text--{-| Decode a `Maybe`-->>> input (maybe natural) "Some 1"-Just 1--}-maybe :: Decoder a -> Decoder (Maybe a)-maybe (Decoder extractIn expectedIn) = Decoder extractOut expectedOut-  where-    extractOut (Some e    ) = fmap Just (extractIn e)-    extractOut (App None _) = pure Nothing-    extractOut expr         = typeError expectedOut expr--    expectedOut = App Optional <$> expectedIn--{-| Decode a `Seq`-->>> input (sequence natural) "[1, 2, 3]"-fromList [1,2,3]--}-sequence :: Decoder a -> Decoder (Seq a)-sequence (Decoder extractIn expectedIn) = Decoder extractOut expectedOut-  where-    extractOut (ListLit _ es) = traverse extractIn es-    extractOut expr           = typeError expectedOut expr--    expectedOut = App List <$> expectedIn--{-| Decode a list-->>> input (list natural) "[1, 2, 3]"-[1,2,3]--}-list :: Decoder a -> Decoder [a]-list = fmap Data.Foldable.toList . sequence--{-| Decode a `Vector`-->>> input (vector natural) "[1, 2, 3]"-[1,2,3]--}-vector :: Decoder a -> Decoder (Vector a)-vector = fmap Data.Vector.fromList . list--{-| Decode a Dhall function into a Haskell function-->>> f <- input (function inject bool) "Natural/even" :: IO (Natural -> Bool)->>> f 0-True->>> f 1-False--}-function-    :: Encoder a-    -> Decoder b-    -> Decoder (a -> b)-function = functionWith defaultInputNormalizer--{-| Decode a Dhall function into a Haskell function using the specified normalizer-->>> f <- input (functionWith defaultInputNormalizer inject bool) "Natural/even" :: IO (Natural -> Bool)->>> f 0-True->>> f 1-False--}-functionWith-    :: InputNormalizer-    -> Encoder a-    -> Decoder b-    -> Decoder (a -> b)-functionWith inputNormalizer (Encoder {..}) (Decoder extractIn expectedIn) =-    Decoder extractOut expectedOut-  where-    normalizer_ = Just (getInputNormalizer inputNormalizer)--    extractOut e = pure (\i -> case extractIn (Core.normalizeWith normalizer_ (App e (embed i))) of-        Success o  -> o-        Failure _e -> error "FromDhall: You cannot decode a function if it does not have the correct type" )--    expectedOut = Pi "_" declared <$> expectedIn--{-| Decode a `Data.Set.Set` from a `List`-->>> input (setIgnoringDuplicates natural) "[1, 2, 3]"-fromList [1,2,3]--Duplicate elements are ignored.-->>> input (setIgnoringDuplicates natural) "[1, 1, 3]"-fromList [1,3]---}-setIgnoringDuplicates :: (Ord a) => Decoder a -> Decoder (Data.Set.Set a)-setIgnoringDuplicates = fmap Data.Set.fromList . list--{-| Decode a `Data.HashSet.HashSet` from a `List`-->>> input (hashSetIgnoringDuplicates natural) "[1, 2, 3]"-fromList [1,2,3]--Duplicate elements are ignored.-->>> input (hashSetIgnoringDuplicates natural) "[1, 1, 3]"-fromList [1,3]---}-hashSetIgnoringDuplicates :: (Hashable a, Ord a)-                          => Decoder a-                          -> Decoder (Data.HashSet.HashSet a)-hashSetIgnoringDuplicates = fmap Data.HashSet.fromList . list--{-| Decode a `Data.Set.Set` from a `List` with distinct elements-->>> input (setFromDistinctList natural) "[1, 2, 3]"-fromList [1,2,3]--An error is thrown if the list contains duplicates.--> >>> input (setFromDistinctList natural) "[1, 1, 3]"-> *** Exception: Error: Failed extraction->-> The expression type-checked successfully but the transformation to the target-> type failed with the following error:->-> One duplicate element in the list: 1->--> >>> input (setFromDistinctList natural) "[1, 1, 3, 3]"-> *** Exception: Error: Failed extraction->-> The expression type-checked successfully but the transformation to the target-> type failed with the following error:->-> 2 duplicates were found in the list, including 1->---}-setFromDistinctList :: (Ord a, Show a) => Decoder a -> Decoder (Data.Set.Set a)-setFromDistinctList = setHelper Data.Set.size Data.Set.fromList--{-| Decode a `Data.HashSet.HashSet` from a `List` with distinct elements-->>> input (hashSetFromDistinctList natural) "[1, 2, 3]"-fromList [1,2,3]--An error is thrown if the list contains duplicates.--> >>> input (hashSetFromDistinctList natural) "[1, 1, 3]"-> *** Exception: Error: Failed extraction->-> The expression type-checked successfully but the transformation to the target-> type failed with the following error:->-> One duplicate element in the list: 1->--> >>> input (hashSetFromDistinctList natural) "[1, 1, 3, 3]"-> *** Exception: Error: Failed extraction->-> The expression type-checked successfully but the transformation to the target-> type failed with the following error:->-> 2 duplicates were found in the list, including 1->---}-hashSetFromDistinctList :: (Hashable a, Ord a, Show a)-                        => Decoder a-                        -> Decoder (Data.HashSet.HashSet a)-hashSetFromDistinctList = setHelper Data.HashSet.size Data.HashSet.fromList---setHelper :: (Eq a, Foldable t, Show a)-          => (t a -> Int)-          -> ([a] -> t a)-          -> Decoder a-          -> Decoder (t a)-setHelper size toSet (Decoder extractIn expectedIn) = Decoder extractOut expectedOut-  where-    extractOut (ListLit _ es) = case traverse extractIn es of-        Success vSeq-            | sameSize               -> Success vSet-            | otherwise              -> extractError err-          where-            vList = Data.Foldable.toList vSeq-            vSet = toSet vList-            sameSize = size vSet == Data.Sequence.length vSeq-            duplicates = vList Data.List.\\ Data.Foldable.toList vSet-            err | length duplicates == 1 =-                     "One duplicate element in the list: "-                     <> (Data.Text.pack $ show $ head duplicates)-                | otherwise              = Data.Text.pack $ unwords-                     [ show $ length duplicates-                     , "duplicates were found in the list, including"-                     , show $ head duplicates-                     ]-        Failure f -> Failure f-    extractOut expr = typeError expectedOut expr--    expectedOut = App List <$> expectedIn--{-| Decode a `Map` from a @toMap@ expression or generally a @Prelude.Map.Type@-->>> input (Dhall.map strictText bool) "toMap { a = True, b = False }"-fromList [("a",True),("b",False)]->>> input (Dhall.map strictText bool) "[ { mapKey = \"foo\", mapValue = True } ]"-fromList [("foo",True)]--If there are duplicate @mapKey@s, later @mapValue@s take precedence:-->>> let expr = "[ { mapKey = 1, mapValue = True }, { mapKey = 1, mapValue = False } ]"->>> input (Dhall.map natural bool) expr-fromList [(1,False)]---}-map :: Ord k => Decoder k -> Decoder v -> Decoder (Map k v)-map k v = fmap Data.Map.fromList (list (pairFromMapEntry k v))--{-| Decode a `HashMap` from a @toMap@ expression or generally a @Prelude.Map.Type@-->>> input (Dhall.hashMap strictText bool) "toMap { a = True, b = False }"-fromList [("a",True),("b",False)]->>> input (Dhall.hashMap strictText bool) "[ { mapKey = \"foo\", mapValue = True } ]"-fromList [("foo",True)]--If there are duplicate @mapKey@s, later @mapValue@s take precedence:-->>> let expr = "[ { mapKey = 1, mapValue = True }, { mapKey = 1, mapValue = False } ]"->>> input (Dhall.hashMap natural bool) expr-fromList [(1,False)]---}-hashMap :: (Eq k, Hashable k) => Decoder k -> Decoder v -> Decoder (HashMap k v)-hashMap k v = fmap HashMap.fromList (list (pairFromMapEntry k v))--{-| Decode a tuple from a @Prelude.Map.Entry@ record-->>> input (pairFromMapEntry strictText natural) "{ mapKey = \"foo\", mapValue = 3 }"-("foo",3)--}-pairFromMapEntry :: Decoder k -> Decoder v -> Decoder (k, v)-pairFromMapEntry k v = Decoder extractOut expectedOut-  where-    extractOut (RecordLit kvs)-        | Just key <- Core.recordFieldValue <$> Dhall.Map.lookup "mapKey" kvs-        , Just value <- Core.recordFieldValue <$> Dhall.Map.lookup "mapValue" kvs-            = liftA2 (,) (extract k key) (extract v value)-    extractOut expr = typeError expectedOut expr--    expectedOut = do-        k' <- Core.makeRecordField <$> expected k-        v' <- Core.makeRecordField <$> expected v-        pure $ Record $ Dhall.Map.fromList-            [ ("mapKey", k')-            , ("mapValue", v')]--{-| Decode @()@ from an empty record.-->>> input unit "{=}"  -- GHC doesn't print the result if it is ()---}-unit :: Decoder ()-unit = Decoder {..}-  where-    extract (RecordLit fields)-        | Data.Foldable.null fields = pure ()-    extract expr = typeError expected expr--    expected = pure $ Record mempty--{-| Decode 'Void' from an empty union.--Since @<>@ is uninhabited, @'input' 'void'@ will always fail.--}-void :: Decoder Void-void = union mempty--{-| Decode a `String`-->>> input string "\"ABC\""-"ABC"---}-string :: Decoder String-string = Data.Text.Lazy.unpack <$> lazyText--{-| Given a pair of `Decoder`s, decode a tuple-record into their pairing.-->>> input (pair natural bool) "{ _1 = 42, _2 = False }"-(42,False)--}-pair :: Decoder a -> Decoder b -> Decoder (a, b)-pair l r = Decoder extractOut expectedOut-  where-    extractOut expr@(RecordLit fields) =-      (,) <$> Data.Maybe.maybe (typeError expectedOut expr) (extract l)-                (Core.recordFieldValue <$> Dhall.Map.lookup "_1" fields)-          <*> Data.Maybe.maybe (typeError expectedOut expr) (extract r)-                (Core.recordFieldValue <$> Dhall.Map.lookup "_2" fields)-    extractOut expr = typeError expectedOut expr--    expectedOut = do-        l' <- Core.makeRecordField <$> expected l-        r' <- Core.makeRecordField <$> expected r-        pure $ Record $ Dhall.Map.fromList-            [ ("_1", l')-            , ("_2", r')]--{-| Any value that implements `FromDhall` can be automatically decoded based on-    the inferred return type of `input`-->>> input auto "[1, 2, 3]" :: IO (Vector Natural)-[1,2,3]->>> input auto "toMap { a = False, b = True }" :: IO (Map Text Bool)-fromList [("a",False),("b",True)]--    This class auto-generates a default implementation for types that-    implement `Generic`.  This does not auto-generate an instance for recursive-    types.--    The default instance can be tweaked using 'genericAutoWith' and custom-    'InterpretOptions', or using-    [DerivingVia](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-DerivingVia)-    and 'Dhall.Deriving.Codec' from "Dhall.Deriving".--}-class FromDhall a where-    autoWith :: InputNormalizer -> Decoder a-    default autoWith-        :: (Generic a, GenericFromDhall a (Rep a)) => InputNormalizer -> Decoder a-    autoWith _ = genericAuto--{-| A compatibility alias for `FromDhall`--This will eventually be removed.--}-type Interpret = FromDhall--instance FromDhall Void where-    autoWith _ = void--instance FromDhall () where-    autoWith _ = unit--instance FromDhall Bool where-    autoWith _ = bool--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--instance FromDhall Double where-    autoWith _ = double--instance {-# OVERLAPS #-} FromDhall [Char] where-    autoWith _ = string--instance FromDhall Data.Text.Lazy.Text where-    autoWith _ = lazyText--instance FromDhall Text where-    autoWith _ = strictText--instance FromDhall a => FromDhall (Maybe a) where-    autoWith opts = maybe (autoWith opts)--instance FromDhall a => FromDhall (Seq a) where-    autoWith opts = sequence (autoWith opts)--instance FromDhall a => FromDhall [a] where-    autoWith opts = list (autoWith opts)--instance FromDhall a => FromDhall (Vector a) where-    autoWith opts = vector (autoWith opts)--{-| Note that this instance will throw errors in the presence of duplicates in-    the list. To ignore duplicates, use `setIgnoringDuplicates`.--}-instance (FromDhall a, Ord a, Show a) => FromDhall (Data.Set.Set a) where-    autoWith opts = setFromDistinctList (autoWith opts)--{-| Note that this instance will throw errors in the presence of duplicates in-    the list. To ignore duplicates, use `hashSetIgnoringDuplicates`.--}-instance (FromDhall a, Hashable a, Ord a, Show a) => FromDhall (Data.HashSet.HashSet a) where-    autoWith inputNormalizer = hashSetFromDistinctList (autoWith inputNormalizer)--instance (Ord k, FromDhall k, FromDhall v) => FromDhall (Map k v) where-    autoWith inputNormalizer = Dhall.map (autoWith inputNormalizer) (autoWith inputNormalizer)--instance (Eq k, Hashable k, FromDhall k, FromDhall v) => FromDhall (HashMap k v) where-    autoWith inputNormalizer = Dhall.hashMap (autoWith inputNormalizer) (autoWith inputNormalizer)--instance (ToDhall a, FromDhall b) => FromDhall (a -> b) where-    autoWith inputNormalizer =-        functionWith inputNormalizer (injectWith inputNormalizer) (autoWith inputNormalizer)--instance (FromDhall a, FromDhall b) => FromDhall (a, b)--{-| Use the default input normalizer for interpreting a configuration file--> auto = autoWith defaultInputNormalizer--}-auto :: FromDhall a => Decoder a-auto = autoWith defaultInputNormalizer--{-| This type is exactly the same as `Data.Fix.Fix` except with a different-    `FromDhall` instance.  This intermediate type simplifies the implementation-    of the inner loop for the `FromDhall` instance for `Fix`--}-newtype Result f = Result { _unResult :: f (Result f) }--resultToFix :: Functor f => Result f -> Fix f-resultToFix (Result x) = Fix (fmap resultToFix x)--instance FromDhall (f (Result f)) => FromDhall (Result f) where-    autoWith inputNormalizer = Decoder {..}-      where-        extract (App _ expr) =-            fmap Result (Dhall.extract (autoWith inputNormalizer) expr)-        extract expr = typeError expected expr--        expected = pure "result"---- | You can use this instance to marshal recursive types from Dhall to Haskell.------ Here is an example use of this instance:------ > {-# LANGUAGE DeriveAnyClass     #-}--- > {-# LANGUAGE DeriveFoldable     #-}--- > {-# LANGUAGE DeriveFunctor      #-}--- > {-# LANGUAGE DeriveTraversable  #-}--- > {-# LANGUAGE DeriveGeneric      #-}--- > {-# LANGUAGE KindSignatures     #-}--- > {-# LANGUAGE QuasiQuotes        #-}--- > {-# LANGUAGE StandaloneDeriving #-}--- > {-# LANGUAGE TypeFamilies       #-}--- > {-# LANGUAGE TemplateHaskell    #-}--- >--- > import Data.Fix (Fix(..))--- > import Data.Text (Text)--- > import Dhall (FromDhall)--- > import GHC.Generics (Generic)--- > import Numeric.Natural (Natural)--- >--- > import qualified Data.Fix                 as Fix--- > import qualified Data.Functor.Foldable    as Foldable--- > import qualified Data.Functor.Foldable.TH as TH--- > import qualified Dhall--- > import qualified NeatInterpolation--- >--- > data Expr--- >     = Lit Natural--- >     | Add Expr Expr--- >     | Mul Expr Expr--- >     deriving (Show)--- >--- > TH.makeBaseFunctor ''Expr--- >--- > deriving instance Generic (ExprF a)--- > deriving instance FromDhall a => FromDhall (ExprF a)--- >--- > example :: Text--- > example = [NeatInterpolation.text|--- >     \(Expr : Type)--- > ->  let ExprF =--- >           < LitF :--- >               Natural--- >           | AddF :--- >               { _1 : Expr, _2 : Expr }--- >           | MulF :--- >               { _1 : Expr, _2 : Expr }--- >           >--- >--- >     in      \(Fix : ExprF -> Expr)--- >         ->  let Lit = \(x : Natural) -> Fix (ExprF.LitF x)--- >--- >             let Add =--- >                       \(x : Expr)--- >                   ->  \(y : Expr)--- >                   ->  Fix (ExprF.AddF { _1 = x, _2 = y })--- >--- >             let Mul =--- >                       \(x : Expr)--- >                   ->  \(y : Expr)--- >                   ->  Fix (ExprF.MulF { _1 = x, _2 = y })--- >--- >             in  Add (Mul (Lit 3) (Lit 7)) (Add (Lit 1) (Lit 2))--- > |]--- >--- > convert :: Fix ExprF -> Expr--- > convert = Fix.foldFix Foldable.embed--- >--- > main :: IO ()--- > main = do--- >     x <- Dhall.input Dhall.auto example :: IO (Fix ExprF)--- >--- >     print (convert x :: Expr)-instance (Functor f, FromDhall (f (Result f))) => FromDhall (Fix f) where-    autoWith inputNormalizer = Decoder {..}-      where-        extract expr0 = extract0 expr0-          where-            die = typeError expected expr0--            extract0 (Lam (FunctionBinding { functionBindingVariable = x }) expr) =-                extract1 (rename x "result" expr)-            extract0  _             = die--            extract1 (Lam (FunctionBinding { functionBindingVariable = y }) expr) =-                extract2 (rename y "Make" expr)-            extract1  _             = die--            extract2 expr = fmap resultToFix (Dhall.extract (autoWith inputNormalizer) expr)--            rename a b expr-                | a /= b    = Core.subst (V a 0) (Var (V b 0)) (Core.shift 1 (V b 0) expr)-                | otherwise = expr--        expected = (\x -> Pi "result" (Const Core.Type) (Pi "Make" (Pi "_" x "result") "result"))-            <$> Dhall.expected (autoWith inputNormalizer :: Decoder (f (Result f)))--{-| `genericAuto` is the default implementation for `auto` if you derive-    `FromDhall`.  The difference is that you can use `genericAuto` without-    having to explicitly provide a `FromDhall` instance for a type as long as-    the type derives `Generic`--}-genericAuto :: (Generic a, GenericFromDhall a (Rep a)) => Decoder a-genericAuto = genericAutoWith defaultInterpretOptions--{-| `genericAutoWith` is a configurable version of `genericAuto`.--}-genericAutoWith :: (Generic a, GenericFromDhall a (Rep a)) => InterpretOptions -> Decoder a-genericAutoWith options = withProxy (\p -> fmap to (evalState (genericAutoWithNormalizer p defaultInputNormalizer options) 1))-    where-        withProxy :: (Proxy a -> Decoder a) -> Decoder a-        withProxy f = f Proxy---{-| Use these options to tweak how Dhall derives a generic implementation of-    `FromDhall`--}-data InterpretOptions = InterpretOptions-    { fieldModifier       :: Text -> Text-    -- ^ Function used to transform Haskell field names into their corresponding-    --   Dhall field names-    , constructorModifier :: Text -> Text-    -- ^ Function used to transform Haskell constructor names into their-    --   corresponding Dhall alternative names-    , singletonConstructors :: SingletonConstructors-    -- ^ Specify how to handle constructors with only one field.  The default is-    --   `Smart`-    }---- | This is only used by the `FromDhall` instance for functions in order---   to normalize the function input before marshaling the input into a---   Dhall expression-newtype InputNormalizer = InputNormalizer-  { getInputNormalizer :: Core.ReifiedNormalizer Void }---- | Default normalization-related settings (no custom normalization)-defaultInputNormalizer :: InputNormalizer-defaultInputNormalizer = InputNormalizer- { getInputNormalizer = Core.ReifiedNormalizer (const (pure Nothing)) }--{-| This type specifies how to model a Haskell constructor with 1 field in-    Dhall--    For example, consider the following Haskell datatype definition:--    > data Example = Foo { x :: Double } | Bar Double--    Depending on which option you pick, the corresponding Dhall type could be:--    > < Foo : Double | Bar : Double >                   -- Bare--    > < Foo : { x : Double } | Bar : { _1 : Double } >  -- Wrapped--    > < Foo : { x : Double } | Bar : Double >           -- Smart--}-data SingletonConstructors-    = Bare-    -- ^ Never wrap the field in a record-    | Wrapped-    -- ^ Always wrap the field in a record-    | Smart-    -- ^ Only fields in a record if they are named--{-| Default interpret options for generics-based instances,-    which you can tweak or override, like this:--> genericAutoWith->     (defaultInterpretOptions { fieldModifier = Data.Text.Lazy.dropWhile (== '_') })--}-defaultInterpretOptions :: InterpretOptions-defaultInterpretOptions = InterpretOptions-    { fieldModifier =-          id-    , constructorModifier =-          id-    , singletonConstructors =-          Smart-    }--{-| This is the underlying class that powers the `FromDhall` class's support-    for automatically deriving a generic implementation--}-class GenericFromDhall t f where-    genericAutoWithNormalizer :: Proxy t -> InputNormalizer -> InterpretOptions -> State Int (Decoder (f a))--instance GenericFromDhall t f => GenericFromDhall t (M1 D d f) where-    genericAutoWithNormalizer p inputNormalizer options = do-        res <- genericAutoWithNormalizer p inputNormalizer options-        pure (fmap M1 res)--instance GenericFromDhall t V1 where-    genericAutoWithNormalizer _ _ _ = pure Decoder {..}-      where-        extract expr = typeError expected expr--        expected = pure $ Union mempty--unsafeExpectUnion-    :: Text -> Expr Src Void -> Dhall.Map.Map Text (Maybe (Expr Src Void))-unsafeExpectUnion _ (Union kts) =-    kts-unsafeExpectUnion name expression =-    Core.internalError-        (name <> ": Unexpected constructor: " <> Core.pretty expression)--unsafeExpectRecord-    :: Text -> Expr Src Void -> Dhall.Map.Map Text (RecordField Src Void)-unsafeExpectRecord _ (Record kts) =-    kts-unsafeExpectRecord name expression =-    Core.internalError-        (name <> ": Unexpected constructor: " <> Core.pretty expression)--unsafeExpectUnionLit-    :: Text-    -> Expr Src Void-    -> (Text, Maybe (Expr Src Void))-unsafeExpectUnionLit _ (Field (Union _) (Core.fieldSelectionLabel -> k)) =-    (k, Nothing)-unsafeExpectUnionLit _ (App (Field (Union _) (Core.fieldSelectionLabel -> k)) v) =-    (k, Just v)-unsafeExpectUnionLit name expression =-    Core.internalError-        (name <> ": Unexpected constructor: " <> Core.pretty expression)--unsafeExpectRecordLit-    :: Text -> Expr Src Void -> Dhall.Map.Map Text (RecordField Src Void)-unsafeExpectRecordLit _ (RecordLit kvs) =-    kvs-unsafeExpectRecordLit name expression =-    Core.internalError-        (name <> ": Unexpected constructor: " <> Core.pretty expression)--notEmptyRecordLit :: Expr s a -> Maybe (Expr s a)-notEmptyRecordLit e = case e of-    RecordLit m | null m -> Nothing-    _                    -> Just e--notEmptyRecord :: Expr s a -> Maybe (Expr s a)-notEmptyRecord e = case e of-    Record m | null m -> Nothing-    _                 -> Just e-extractUnionConstructor-    :: Expr s a -> Maybe (Text, Expr s a, Dhall.Map.Map Text (Maybe (Expr s a)))-extractUnionConstructor (App (Field (Union kts) (Core.fieldSelectionLabel -> fld)) e) =-  return (fld, e, Dhall.Map.delete fld kts)-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)--instance (GenericFromDhallUnion t f1, GenericFromDhallUnion t f2) => GenericFromDhallUnion t (f1 :+: f2) where-  genericUnionAutoWithNormalizer p inputNormalizer options =-    (<>)-      (L1 <$> genericUnionAutoWithNormalizer p inputNormalizer options)-      (R1 <$> genericUnionAutoWithNormalizer p inputNormalizer options)--instance (Constructor c1, GenericFromDhall t f1) => GenericFromDhallUnion t (M1 C c1 f1) where-  genericUnionAutoWithNormalizer p inputNormalizer options@(InterpretOptions {..}) =-    constructor name (evalState (genericAutoWithNormalizer p inputNormalizer options) 1)-    where-      n :: M1 C c1 f1 a-      n = undefined--      name = constructorModifier (Data.Text.pack (conName n))--instance GenericFromDhallUnion t (f :+: g) => GenericFromDhall t (f :+: g) where-  genericAutoWithNormalizer p inputNormalizer options =-    pure (union (genericUnionAutoWithNormalizer p inputNormalizer options))--instance GenericFromDhall t f => GenericFromDhall t (M1 C c f) where-    genericAutoWithNormalizer p inputNormalizer options = do-        res <- genericAutoWithNormalizer p inputNormalizer options-        pure (fmap M1 res)--instance GenericFromDhall t U1 where-    genericAutoWithNormalizer _ _ _ = pure (Decoder {..})-      where-        extract _ = pure U1--        expected = pure expected'--        expected' = Record (Dhall.Map.fromList [])--getSelName :: Selector s => M1 i s f a -> State Int Text-getSelName n = case selName n of-    "" -> do i <- get-             put (i + 1)-             pure (Data.Text.pack ("_" ++ show i))-    nn -> pure (Data.Text.pack nn)--instance (GenericFromDhall t (f :*: g), GenericFromDhall t (h :*: i)) => GenericFromDhall t ((f :*: g) :*: (h :*: i)) where-    genericAutoWithNormalizer p inputNormalizer options = do-        Decoder extractL expectedL <- genericAutoWithNormalizer p inputNormalizer options-        Decoder extractR expectedR <- genericAutoWithNormalizer p inputNormalizer options--        let ktsL = unsafeExpectRecord "genericAutoWithNormalizer (:*:)" <$> expectedL-        let ktsR = unsafeExpectRecord "genericAutoWithNormalizer (:*:)" <$> expectedR--        let expected = Record <$> (Dhall.Map.union <$> ktsL <*> ktsR)--        let extract expression =-                liftA2 (:*:) (extractL expression) (extractR expression)--        return (Decoder {..})--instance (GenericFromDhall t (f :*: g), Selector s, FromDhall a) => GenericFromDhall t ((f :*: g) :*: M1 S s (K1 i a)) where-    genericAutoWithNormalizer p inputNormalizer options@InterpretOptions{..} = do-        let nR :: M1 S s (K1 i a) r-            nR = undefined--        nameR <- fmap fieldModifier (getSelName nR)--        Decoder extractL expectedL <- genericAutoWithNormalizer p inputNormalizer options--        let Decoder extractR expectedR = autoWith inputNormalizer--        let ktsL = unsafeExpectRecord "genericAutoWithNormalizer (:*:)" <$> expectedL--        let expected = Record <$> (Dhall.Map.insert nameR . Core.makeRecordField <$> expectedR <*> ktsL)--        let extract expression = do-                let die = typeError expected expression--                case expression of-                    RecordLit kvs ->-                        case Core.recordFieldValue <$> Dhall.Map.lookup nameR kvs of-                            Just expressionR ->-                                liftA2 (:*:)-                                    (extractL expression)-                                    (fmap (M1 . K1) (extractR expressionR))-                            _ -> die-                    _ -> die--        return (Decoder {..})--instance (Selector s, FromDhall a, GenericFromDhall t (f :*: g)) => GenericFromDhall t (M1 S s (K1 i a) :*: (f :*: g)) where-    genericAutoWithNormalizer p inputNormalizer options@InterpretOptions{..} = do-        let nL :: M1 S s (K1 i a) r-            nL = undefined--        nameL <- fmap fieldModifier (getSelName nL)--        let Decoder extractL expectedL = autoWith inputNormalizer--        Decoder extractR expectedR <- genericAutoWithNormalizer p inputNormalizer options--        let ktsR = unsafeExpectRecord "genericAutoWithNormalizer (:*:)" <$> expectedR--        let expected = Record <$> (Dhall.Map.insert nameL . Core.makeRecordField <$> expectedL <*> ktsR)--        let extract expression = do-                let die = typeError expected expression--                case expression of-                    RecordLit kvs ->-                        case Core.recordFieldValue <$> Dhall.Map.lookup nameL kvs of-                            Just expressionL ->-                                liftA2 (:*:)-                                    (fmap (M1 . K1) (extractL expressionL))-                                    (extractR expression)-                            _ -> die-                    _ -> die--        return (Decoder {..})--instance {-# OVERLAPPING #-} GenericFromDhall a1 (M1 S s1 (K1 i1 a1) :*: M1 S s2 (K1 i2 a2)) where-    genericAutoWithNormalizer _ _ _ = pure $ Decoder-        { extract = \_ -> Failure $ DhallErrors $ pure $ ExpectedTypeError RecursiveTypeError-        , expected = Failure $ DhallErrors $ pure RecursiveTypeError-        }--instance {-# OVERLAPPING #-} GenericFromDhall a2 (M1 S s1 (K1 i1 a1) :*: M1 S s2 (K1 i2 a2)) where-    genericAutoWithNormalizer _ _ _ = pure $ Decoder-        { extract = \_ -> Failure $ DhallErrors $ pure $ ExpectedTypeError RecursiveTypeError-        , expected = Failure $ DhallErrors $ pure RecursiveTypeError-        }--instance {-# OVERLAPPABLE #-} (Selector s1, Selector s2, FromDhall a1, FromDhall a2) => GenericFromDhall t (M1 S s1 (K1 i1 a1) :*: M1 S s2 (K1 i2 a2)) where-    genericAutoWithNormalizer _ inputNormalizer InterpretOptions{..} = do-        let nL :: M1 S s1 (K1 i1 a1) r-            nL = undefined--        let nR :: M1 S s2 (K1 i2 a2) r-            nR = undefined--        nameL <- fmap fieldModifier (getSelName nL)-        nameR <- fmap fieldModifier (getSelName nR)--        let Decoder extractL expectedL = autoWith inputNormalizer-        let Decoder extractR expectedR = autoWith inputNormalizer--        let expected = do-                l <- Core.makeRecordField <$> expectedL-                r <- Core.makeRecordField <$> expectedR-                pure $ Record-                    (Dhall.Map.fromList-                        [ (nameL, l)-                        , (nameR, r)-                        ]-                    )--        let extract expression = do-                let die = typeError expected expression--                case expression of-                    RecordLit kvs ->-                        case liftA2 (,) (Dhall.Map.lookup nameL kvs) (Dhall.Map.lookup nameR kvs) of-                            Just (expressionL, expressionR) ->-                                liftA2 (:*:)-                                    (fmap (M1 . K1) (extractL $ Core.recordFieldValue expressionL))-                                    (fmap (M1 . K1) (extractR $ Core.recordFieldValue expressionR))-                            Nothing -> die-                    _ -> die--        return (Decoder {..})--instance {-# OVERLAPPING #-} GenericFromDhall a (M1 S s (K1 i a)) where-    genericAutoWithNormalizer _ _ _ = pure $ Decoder-        { extract = \_ -> Failure $ DhallErrors $ pure $ ExpectedTypeError RecursiveTypeError-        , expected = Failure $ DhallErrors $ pure RecursiveTypeError-        }--instance {-# OVERLAPPABLE #-} (Selector s, FromDhall a) => GenericFromDhall t (M1 S s (K1 i a)) where-    genericAutoWithNormalizer _ inputNormalizer InterpretOptions{..} = do-        let n :: M1 S s (K1 i a) r-            n = undefined--        name <- fmap fieldModifier (getSelName n)--        let Decoder { extract = extract', expected = expected'} = autoWith inputNormalizer--        let expected =-                case singletonConstructors of-                    Bare ->-                        expected'-                    Smart | selName n == "" ->-                        expected'-                    _ ->-                        Record . Dhall.Map.singleton name . Core.makeRecordField <$> expected'--        let extract0 expression = fmap (M1 . K1) (extract' expression)--        let extract1 expression = do-                let die = typeError expected expression--                case expression of-                    RecordLit kvs ->-                        case Core.recordFieldValue <$> Dhall.Map.lookup name kvs of-                            Just subExpression ->-                                fmap (M1 . K1) (extract' subExpression)-                            Nothing ->-                                die-                    _ -> die--        let extract =-                case singletonConstructors of-                    Bare                    -> extract0-                    Smart | selName n == "" -> extract0-                    _                       -> extract1--        return (Decoder {..})--{-| An @(Encoder a)@ represents a way to marshal a value of type @\'a\'@ from-    Haskell into Dhall--}-data Encoder a = Encoder-    { embed    :: a -> Expr Src Void-    -- ^ Embeds a Haskell value as a Dhall expression-    , declared :: Expr Src Void-    -- ^ Dhall type of the Haskell value-    }--instance Contravariant Encoder where-    contramap f (Encoder embed declared) = Encoder embed' declared-      where-        embed' x = embed (f x)--{-| This class is used by `FromDhall` instance for functions:--> instance (ToDhall a, FromDhall b) => FromDhall (a -> b)--    You can convert Dhall functions with "simple" inputs (i.e. instances of this-    class) into Haskell functions.  This works by:--    * Marshaling the input to the Haskell function into a Dhall expression (i.e.-      @x :: Expr Src Void@)-    * Applying the Dhall function (i.e. @f :: Expr Src Void@) to the Dhall input-      (i.e. @App f x@)-    * Normalizing the syntax tree (i.e. @normalize (App f x)@)-    * Marshaling the resulting Dhall expression back into a Haskell value--    This class auto-generates a default implementation for types that-    implement `Generic`.  This does not auto-generate an instance for recursive-    types.--    The default instance can be tweaked using 'genericToDhallWith' and custom-    'InterpretOptions', or using-    [DerivingVia](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-DerivingVia)-    and 'Dhall.Deriving.Codec' from "Dhall.Deriving".--}-class ToDhall a where-    injectWith :: InputNormalizer -> Encoder a-    default injectWith-        :: (Generic a, GenericToDhall (Rep a)) => InputNormalizer -> Encoder a-    injectWith _ = genericToDhall--{-| A compatibility alias for `ToDhall`--This will eventually be removed.--}-type Inject = ToDhall--{-| Use the default input normalizer for injecting a value--> inject = injectWith defaultInputNormalizer--}-inject :: ToDhall a => Encoder a-inject = injectWith defaultInputNormalizer--{-| Use the default options for injecting a value, whose structure is-determined generically.--This can be used when you want to use 'ToDhall' on types that you don't-want to define orphan instances for.--}-genericToDhall-  :: (Generic a, GenericToDhall (Rep a)) => Encoder a-genericToDhall-    = genericToDhallWith defaultInterpretOptions--{-| Use custom options for injecting a value, whose structure is-determined generically.--This can be used when you want to use 'ToDhall' on types that you don't-want to define orphan instances for.--}-genericToDhallWith-  :: (Generic a, GenericToDhall (Rep a)) => InterpretOptions -> Encoder a-genericToDhallWith options-    = contramap GHC.Generics.from (evalState (genericToDhallWithNormalizer defaultInputNormalizer options) 1)--instance ToDhall Void where-    injectWith _ = Encoder {..}-      where-        embed = Data.Void.absurd--        declared = Union mempty--instance ToDhall Bool where-    injectWith _ = Encoder {..}-      where-        embed = BoolLit--        declared = Bool--instance ToDhall Data.Text.Lazy.Text where-    injectWith _ = Encoder {..}-      where-        embed text =-            TextLit (Chunks [] (Data.Text.Lazy.toStrict text))--        declared = Text--instance ToDhall Text where-    injectWith _ = Encoder {..}-      where-        embed text = TextLit (Chunks [] text)--        declared = Text--instance {-# OVERLAPS #-} ToDhall String where-    injectWith inputNormalizer =-        contramap Data.Text.pack (injectWith inputNormalizer :: Encoder Text)--instance ToDhall Natural where-    injectWith _ = Encoder {..}-      where-        embed = NaturalLit--        declared = Natural--instance ToDhall Integer where-    injectWith _ = Encoder {..}-      where-        embed = IntegerLit--        declared = Integer--instance ToDhall Int where-    injectWith _ = Encoder {..}-      where-        embed = IntegerLit . toInteger--        declared = Integer--{-|-->>> embed inject (12 :: Word)-NaturalLit 12--}--instance ToDhall Word where-    injectWith _ = Encoder {..}-      where-        embed = NaturalLit . fromIntegral--        declared = Natural--{-|-->>> embed inject (12 :: Word8)-NaturalLit 12--}--instance ToDhall Word8 where-    injectWith _ = Encoder {..}-      where-        embed = NaturalLit . fromIntegral--        declared = Natural--{-|-->>> embed inject (12 :: Word16)-NaturalLit 12--}--instance ToDhall Word16 where-    injectWith _ = Encoder {..}-      where-        embed = NaturalLit . fromIntegral--        declared = Natural--{-|-->>> embed inject (12 :: Word32)-NaturalLit 12--}--instance ToDhall Word32 where-    injectWith _ = Encoder {..}-      where-        embed = NaturalLit . fromIntegral--        declared = Natural--{-|-->>> embed inject (12 :: Word64)-NaturalLit 12--}--instance ToDhall Word64 where-    injectWith _ = Encoder {..}-      where-        embed = NaturalLit . fromIntegral--        declared = Natural--instance ToDhall Double where-    injectWith _ = Encoder {..}-      where-        embed = DoubleLit . DhallDouble--        declared = Double--instance ToDhall Scientific where-    injectWith inputNormalizer =-        contramap Data.Scientific.toRealFloat (injectWith inputNormalizer :: Encoder Double)--instance ToDhall () where-    injectWith _ = Encoder {..}-      where-        embed = const (RecordLit mempty)--        declared = Record mempty--instance ToDhall a => ToDhall (Maybe a) where-    injectWith inputNormalizer = Encoder embedOut declaredOut-      where-        embedOut (Just x ) = Some (embedIn x)-        embedOut  Nothing  = App None declaredIn--        Encoder embedIn declaredIn = injectWith inputNormalizer--        declaredOut = App Optional declaredIn--instance ToDhall a => ToDhall (Seq a) where-    injectWith inputNormalizer = Encoder embedOut declaredOut-      where-        embedOut xs = ListLit listType (fmap embedIn xs)-          where-            listType-                | null xs   = Just (App List declaredIn)-                | otherwise = Nothing--        declaredOut = App List declaredIn--        Encoder embedIn declaredIn = injectWith inputNormalizer--instance ToDhall a => ToDhall [a] where-    injectWith = fmap (contramap Data.Sequence.fromList) injectWith--instance ToDhall a => ToDhall (Vector a) where-    injectWith = fmap (contramap Data.Vector.toList) injectWith--{-| Note that the output list will be sorted-->>> let x = Data.Set.fromList ["mom", "hi" :: Text]->>> prettyExpr $ embed inject x-[ "hi", "mom" ]---}-instance ToDhall a => ToDhall (Data.Set.Set a) where-    injectWith = fmap (contramap Data.Set.toAscList) injectWith--{-| Note that the output list may not be sorted-->>> let x = Data.HashSet.fromList ["hi", "mom" :: Text]->>> prettyExpr $ embed inject x-[ "mom", "hi" ]---}-instance ToDhall a => ToDhall (Data.HashSet.HashSet a) where-    injectWith = fmap (contramap Data.HashSet.toList) injectWith--instance (ToDhall a, ToDhall b) => ToDhall (a, b)--{-| Embed a `Data.Map` as a @Prelude.Map.Type@-->>> prettyExpr $ embed inject (Data.Map.fromList [(1 :: Natural, True)])-[ { mapKey = 1, mapValue = True } ]-->>> prettyExpr $ embed inject (Data.Map.fromList [] :: Data.Map.Map Natural Bool)-[] : List { mapKey : Natural, mapValue : Bool }---}-instance (ToDhall k, ToDhall v) => ToDhall (Data.Map.Map k v) where-    injectWith inputNormalizer = Encoder embedOut declaredOut-      where-        embedOut m = ListLit listType (mapEntries m)-          where-            listType-                | Data.Map.null m = Just declaredOut-                | otherwise       = Nothing--        declaredOut = App List (Record $ Dhall.Map.fromList-                          [ ("mapKey", Core.makeRecordField declaredK)-                          , ("mapValue", Core.makeRecordField declaredV)-                          ])--        mapEntries = Data.Sequence.fromList . fmap recordPair . Data.Map.toList-        recordPair (k, v) = RecordLit $ Dhall.Map.fromList-                                [ ("mapKey", Core.makeRecordField $ embedK k)-                                , ("mapValue", Core.makeRecordField $ embedV v)-                                ]--        Encoder embedK declaredK = injectWith inputNormalizer-        Encoder embedV declaredV = injectWith inputNormalizer--{-| Embed a `Data.HashMap` as a @Prelude.Map.Type@-->>> prettyExpr $ embed inject (HashMap.fromList [(1 :: Natural, True)])-[ { mapKey = 1, mapValue = True } ]-->>> prettyExpr $ embed inject (HashMap.fromList [] :: HashMap Natural Bool)-[] : List { mapKey : Natural, mapValue : Bool }---}-instance (ToDhall k, ToDhall v) => ToDhall (HashMap k v) where-    injectWith inputNormalizer = Encoder embedOut declaredOut-      where-        embedOut m = ListLit listType (mapEntries m)-          where-            listType-                | HashMap.null m = Just declaredOut-                | otherwise       = Nothing--        declaredOut = App List (Record $ Dhall.Map.fromList-                          [ ("mapKey", Core.makeRecordField declaredK)-                          , ("mapValue", Core.makeRecordField declaredV)-                          ])--        mapEntries = Data.Sequence.fromList . fmap recordPair . HashMap.toList-        recordPair (k, v) = RecordLit $ Dhall.Map.fromList-                                [ ("mapKey", Core.makeRecordField $ embedK k)-                                , ("mapValue", Core.makeRecordField $ embedV v)-                                ]--        Encoder embedK declaredK = injectWith inputNormalizer-        Encoder embedV declaredV = injectWith inputNormalizer--{-| This is the underlying class that powers the `FromDhall` class's support-    for automatically deriving a generic implementation--}-class GenericToDhall f where-    genericToDhallWithNormalizer :: InputNormalizer -> InterpretOptions -> State Int (Encoder (f a))--instance GenericToDhall f => GenericToDhall (M1 D d f) where-    genericToDhallWithNormalizer inputNormalizer options = do-        res <- genericToDhallWithNormalizer inputNormalizer options-        pure (contramap unM1 res)--instance GenericToDhall f => GenericToDhall (M1 C c f) where-    genericToDhallWithNormalizer inputNormalizer options = do-        res <- genericToDhallWithNormalizer inputNormalizer options-        pure (contramap unM1 res)--instance (Selector s, ToDhall a) => GenericToDhall (M1 S s (K1 i a)) where-    genericToDhallWithNormalizer inputNormalizer InterpretOptions{..} = do-        let Encoder { embed = embed', declared = declared' } =-                injectWith inputNormalizer--        let n :: M1 S s (K1 i a) r-            n = undefined--        name <- fieldModifier <$> getSelName n--        let embed0 (M1 (K1 x)) = embed' x--        let embed1 (M1 (K1 x)) =-                RecordLit (Dhall.Map.singleton name (Core.makeRecordField $ embed' x))--        let embed =-                case singletonConstructors of-                    Bare                    -> embed0-                    Smart | selName n == "" -> embed0-                    _                       -> embed1--        let declared =-                case singletonConstructors of-                    Bare ->-                        declared'-                    Smart | selName n == "" ->-                        declared'-                    _ ->-                        Record (Dhall.Map.singleton name $ Core.makeRecordField declared')--        return (Encoder {..})--instance (Constructor c1, Constructor c2, GenericToDhall f1, GenericToDhall f2) => GenericToDhall (M1 C c1 f1 :+: M1 C c2 f2) where-    genericToDhallWithNormalizer inputNormalizer options@(InterpretOptions {..}) = pure (Encoder {..})-      where-        embed (L1 (M1 l)) =-            case notEmptyRecordLit (embedL l) of-                Nothing ->-                    Field declared $ Core.makeFieldSelection keyL-                Just valL ->-                    App (Field declared $ Core.makeFieldSelection keyL) valL--        embed (R1 (M1 r)) =-            case notEmptyRecordLit (embedR r) of-                Nothing ->-                    Field declared $ Core.makeFieldSelection keyR-                Just valR ->-                    App (Field declared $ Core.makeFieldSelection keyR) valR--        declared =-            Union-                (Dhall.Map.fromList-                    [ (keyL, notEmptyRecord declaredL)-                    , (keyR, notEmptyRecord declaredR)-                    ]-                )--        nL :: M1 i c1 f1 a-        nL = undefined--        nR :: M1 i c2 f2 a-        nR = undefined--        keyL = constructorModifier (Data.Text.pack (conName nL))-        keyR = constructorModifier (Data.Text.pack (conName nR))--        Encoder embedL declaredL = evalState (genericToDhallWithNormalizer inputNormalizer options) 1-        Encoder embedR declaredR = evalState (genericToDhallWithNormalizer inputNormalizer options) 1--instance (Constructor c, GenericToDhall (f :+: g), GenericToDhall h) => GenericToDhall ((f :+: g) :+: M1 C c h) where-    genericToDhallWithNormalizer inputNormalizer options@(InterpretOptions {..}) = pure (Encoder {..})-      where-        embed (L1 l) =-            case maybeValL of-                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 $ Core.makeFieldSelection keyR-                Just valR -> App (Field declared $ Core.makeFieldSelection keyR) valR--        nR :: M1 i c h a-        nR = undefined--        keyR = constructorModifier (Data.Text.pack (conName nR))--        declared = Union (Dhall.Map.insert keyR (notEmptyRecord declaredR) ktsL)--        Encoder embedL declaredL = evalState (genericToDhallWithNormalizer inputNormalizer options) 1-        Encoder embedR declaredR = evalState (genericToDhallWithNormalizer inputNormalizer options) 1--        ktsL = unsafeExpectUnion "genericToDhallWithNormalizer (:+:)" declaredL--instance (Constructor c, GenericToDhall f, GenericToDhall (g :+: h)) => GenericToDhall (M1 C c f :+: (g :+: h)) where-    genericToDhallWithNormalizer inputNormalizer options@(InterpretOptions {..}) = pure (Encoder {..})-      where-        embed (L1 (M1 l)) =-            case notEmptyRecordLit (embedL l) of-                Nothing   -> Field declared $ Core.makeFieldSelection keyL-                Just valL -> App (Field declared $ Core.makeFieldSelection keyL) valL-        embed (R1 r) =-            case maybeValR of-                Nothing   -> Field declared $ Core.makeFieldSelection keyR-                Just valR -> App (Field declared $ Core.makeFieldSelection keyR) valR-          where-            (keyR, maybeValR) =-                unsafeExpectUnionLit "genericToDhallWithNormalizer (:+:)" (embedR r)--        nL :: M1 i c f a-        nL = undefined--        keyL = constructorModifier (Data.Text.pack (conName nL))--        declared = Union (Dhall.Map.insert keyL (notEmptyRecord declaredL) ktsR)--        Encoder embedL declaredL = evalState (genericToDhallWithNormalizer inputNormalizer options) 1-        Encoder embedR declaredR = evalState (genericToDhallWithNormalizer inputNormalizer options) 1--        ktsR = unsafeExpectUnion "genericToDhallWithNormalizer (:+:)" declaredR--instance (GenericToDhall (f :+: g), GenericToDhall (h :+: i)) => GenericToDhall ((f :+: g) :+: (h :+: i)) where-    genericToDhallWithNormalizer inputNormalizer options = pure (Encoder {..})-      where-        embed (L1 l) =-            case maybeValL of-                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 $ Core.makeFieldSelection keyR-                Just valR -> App (Field declared $ Core.makeFieldSelection keyR) valR-          where-            (keyR, maybeValR) =-                unsafeExpectUnionLit "genericToDhallWithNormalizer (:+:)" (embedR r)--        declared = Union (Dhall.Map.union ktsL ktsR)--        Encoder embedL declaredL = evalState (genericToDhallWithNormalizer inputNormalizer options) 1-        Encoder embedR declaredR = evalState (genericToDhallWithNormalizer inputNormalizer options) 1--        ktsL = unsafeExpectUnion "genericToDhallWithNormalizer (:+:)" declaredL-        ktsR = unsafeExpectUnion "genericToDhallWithNormalizer (:+:)" declaredR--instance (GenericToDhall (f :*: g), GenericToDhall (h :*: i)) => GenericToDhall ((f :*: g) :*: (h :*: i)) where-    genericToDhallWithNormalizer inputNormalizer options = do-        Encoder embedL declaredL <- genericToDhallWithNormalizer inputNormalizer options-        Encoder embedR declaredR <- genericToDhallWithNormalizer inputNormalizer options--        let embed (l :*: r) =-                RecordLit (Dhall.Map.union mapL mapR)-              where-                mapL =-                    unsafeExpectRecordLit "genericToDhallWithNormalizer (:*:)" (embedL l)--                mapR =-                    unsafeExpectRecordLit "genericToDhallWithNormalizer (:*:)" (embedR r)--        let declared = Record (Dhall.Map.union mapL mapR)-              where-                mapL = unsafeExpectRecord "genericToDhallWithNormalizer (:*:)" declaredL-                mapR = unsafeExpectRecord "genericToDhallWithNormalizer (:*:)" declaredR--        pure (Encoder {..})--instance (GenericToDhall (f :*: g), Selector s, ToDhall a) => GenericToDhall ((f :*: g) :*: M1 S s (K1 i a)) where-    genericToDhallWithNormalizer inputNormalizer options@InterpretOptions{..} = do-        let nR :: M1 S s (K1 i a) r-            nR = undefined--        nameR <- fmap fieldModifier (getSelName nR)--        Encoder embedL declaredL <- genericToDhallWithNormalizer inputNormalizer options--        let Encoder embedR declaredR = injectWith inputNormalizer--        let embed (l :*: M1 (K1 r)) =-                RecordLit (Dhall.Map.insert nameR (Core.makeRecordField $ embedR r) mapL)-              where-                mapL =-                    unsafeExpectRecordLit "genericToDhallWithNormalizer (:*:)" (embedL l)--        let declared = Record (Dhall.Map.insert nameR (Core.makeRecordField declaredR) mapL)-              where-                mapL = unsafeExpectRecord "genericToDhallWithNormalizer (:*:)" declaredL--        return (Encoder {..})--instance (Selector s, ToDhall a, GenericToDhall (f :*: g)) => GenericToDhall (M1 S s (K1 i a) :*: (f :*: g)) where-    genericToDhallWithNormalizer inputNormalizer options@InterpretOptions{..} = do-        let nL :: M1 S s (K1 i a) r-            nL = undefined--        nameL <- fmap fieldModifier (getSelName nL)--        let Encoder embedL declaredL = injectWith inputNormalizer--        Encoder embedR declaredR <- genericToDhallWithNormalizer inputNormalizer options--        let embed (M1 (K1 l) :*: r) =-                RecordLit (Dhall.Map.insert nameL (Core.makeRecordField $ embedL l) mapR)-              where-                mapR =-                    unsafeExpectRecordLit "genericToDhallWithNormalizer (:*:)" (embedR r)--        let declared = Record (Dhall.Map.insert nameL (Core.makeRecordField declaredL) mapR)-              where-                mapR = unsafeExpectRecord "genericToDhallWithNormalizer (:*:)" declaredR--        return (Encoder {..})--instance (Selector s1, Selector s2, ToDhall a1, ToDhall a2) => GenericToDhall (M1 S s1 (K1 i1 a1) :*: M1 S s2 (K1 i2 a2)) where-    genericToDhallWithNormalizer inputNormalizer InterpretOptions{..} = do-        let nL :: M1 S s1 (K1 i1 a1) r-            nL = undefined--        let nR :: M1 S s2 (K1 i2 a2) r-            nR = undefined--        nameL <- fmap fieldModifier (getSelName nL)-        nameR <- fmap fieldModifier (getSelName nR)--        let Encoder embedL declaredL = injectWith inputNormalizer-        let Encoder embedR declaredR = injectWith inputNormalizer--        let embed (M1 (K1 l) :*: M1 (K1 r)) =-                RecordLit $-                    Dhall.Map.fromList-                        [ (nameL, Core.makeRecordField $ embedL l)-                        , (nameR, Core.makeRecordField $ embedR r) ]---        let declared =-                Record $ Dhall.Map.fromList-                    [ (nameL, Core.makeRecordField declaredL)-                    , (nameR, Core.makeRecordField declaredR) ]---        return (Encoder {..})--instance GenericToDhall U1 where-    genericToDhallWithNormalizer _ _ = pure (Encoder {..})-      where-        embed _ = RecordLit mempty--        declared = Record mempty--{-| The 'RecordDecoder' applicative functor allows you to build a 'Decoder'-    from a Dhall record.--    For example, let's take the following Haskell data type:-->>> :{-data Project = Project-  { projectName :: Text-  , projectDescription :: Text-  , projectStars :: Natural-  }-:}--    And assume that we have the following Dhall record that we would like to-    parse as a @Project@:--> { name =->     "dhall-haskell"-> , description =->     "A configuration language guaranteed to terminate"-> , stars =->     289-> }--    Our decoder has type 'Decoder' @Project@, but we can't build that out of any-    smaller decoders, as 'Decoder's cannot be combined (they are only 'Functor's).-    However, we can use a 'RecordDecoder' to build a 'Decoder' for @Project@:-->>> :{-project :: Decoder Project-project =-  record-    ( Project <$> field "name" strictText-              <*> field "description" strictText-              <*> field "stars" natural-    )-:}--}--newtype RecordDecoder a =-  RecordDecoder-    ( Data.Functor.Product.Product-        ( Control.Applicative.Const-            (Dhall.Map.Map Text (Expector (Expr Src Void)))-        )-        ( Data.Functor.Compose.Compose ((->) (Expr Src Void)) (Extractor Src Void)-        )-        a-    )-  deriving (Functor, Applicative)----- | Run a 'RecordDecoder' to build a 'Decoder'.-record :: RecordDecoder a -> Dhall.Decoder a-record-    (RecordDecoder-        (Data.Functor.Product.Pair-            (Control.Applicative.Const fields)-            (Data.Functor.Compose.Compose extract)-        )-    ) = Decoder {..}-  where-    expected = Record <$> traverse (fmap Core.makeRecordField) fields----- | Parse a single field of a record.-field :: Text -> Decoder a -> RecordDecoder a-field key (Decoder {..}) =-  RecordDecoder-    ( Data.Functor.Product.Pair-        ( Control.Applicative.Const-            (Dhall.Map.singleton key expected)-        )-        ( Data.Functor.Compose.Compose extractBody )-    )-  where-    extractBody expr@(RecordLit fields) = case Core.recordFieldValue <$> Dhall.Map.lookup key fields of-      Just v -> extract v-      _      -> typeError expected expr-    extractBody expr = typeError expected expr--{-| The 'UnionDecoder' monoid allows you to build a 'Decoder' from a Dhall union--    For example, let's take the following Haskell data type:-->>> :{-data Status = Queued Natural-            | Result Text-            | Errored Text-:}--    And assume that we have the following Dhall union that we would like to-    parse as a @Status@:--> < Result : Text-> | Queued : Natural-> | Errored : Text-> >.Result "Finish successfully"--    Our decoder has type 'Decoder' @Status@, but we can't build that out of any-    smaller decoders, as 'Decoder's cannot be combined (they are only 'Functor's).-    However, we can use a 'UnionDecoder' to build a 'Decoder' for @Status@:-->>> :{-status :: Decoder Status-status = union-  (  ( Queued  <$> constructor "Queued"  natural )-  <> ( Result  <$> constructor "Result"  strictText )-  <> ( Errored <$> constructor "Errored" strictText )-  )-:}---}-newtype UnionDecoder a =-    UnionDecoder-      ( Data.Functor.Compose.Compose (Dhall.Map.Map Text) Decoder a )-  deriving (Functor)--instance Semigroup (UnionDecoder a) where-    (<>) = coerce ((<>) :: Dhall.Map.Map Text (Decoder a) -> Dhall.Map.Map Text (Decoder a) -> Dhall.Map.Map Text (Decoder a))--instance Monoid (UnionDecoder a) where-    mempty = coerce (mempty :: Dhall.Map.Map Text (Decoder a))---- | Run a 'UnionDecoder' to build a 'Decoder'.-union :: UnionDecoder a -> Decoder a-union (UnionDecoder (Data.Functor.Compose.Compose mp)) = Decoder {..}-  where-    extract expr = case expected' of-        Failure e -> Failure $ fmap ExpectedTypeError e-        Success x -> extract' expr x--    extract' e0 mp' = Data.Maybe.maybe (typeError expected e0) (uncurry Dhall.extract) $ do-        (fld, e1, rest) <- extractUnionConstructor e0--        t <- Dhall.Map.lookup fld mp--        guard $-            Core.Union rest `Core.judgmentallyEqual` Core.Union (Dhall.Map.delete fld mp')--        pure (t, e1)--    expected = Union <$> expected'--    expected' = traverse (fmap notEmptyRecord . Dhall.expected) mp---- | Parse a single constructor of a union-constructor :: Text -> Decoder a -> UnionDecoder a-constructor key valueDecoder = UnionDecoder-    ( Data.Functor.Compose.Compose (Dhall.Map.singleton key valueDecoder) )---- | Infix 'divided'-(>*<) :: Divisible f => f a -> f b -> f (a, b)-(>*<) = divided--infixr 5 >*<--{-| The 'RecordEncoder' divisible (contravariant) functor allows you to build-    an 'Encoder' for a Dhall record.--    For example, let's take the following Haskell data type:-->>> :{-data Project = Project-  { projectName :: Text-  , projectDescription :: Text-  , projectStars :: Natural-  }-:}--    And assume that we have the following Dhall record that we would like to-    parse as a @Project@:--> { name =->     "dhall-haskell"-> , description =->     "A configuration language guaranteed to terminate"-> , stars =->     289-> }--    Our encoder has type 'Encoder' @Project@, but we can't build that out of any-    smaller encoders, as 'Encoder's cannot be combined (they are only 'Contravariant's).-    However, we can use an 'RecordEncoder' to build an 'Encoder' for @Project@:-->>> :{-injectProject :: Encoder Project-injectProject =-  recordEncoder-    ( adapt >$< encodeFieldWith "name" inject-            >*< encodeFieldWith "description" inject-            >*< encodeFieldWith "stars" inject-    )-  where-    adapt (Project{..}) = (projectName, (projectDescription, projectStars))-:}--    Or, since we are simply using the `ToDhall` instance to inject each field, we could write-->>> :{-injectProject :: Encoder Project-injectProject =-  recordEncoder-    ( adapt >$< encodeField "name"-            >*< encodeField "description"-            >*< encodeField "stars"-    )-  where-    adapt (Project{..}) = (projectName, (projectDescription, projectStars))-:}---}--newtype RecordEncoder a-  = RecordEncoder (Dhall.Map.Map Text (Encoder a))--instance Contravariant RecordEncoder where-  contramap f (RecordEncoder encodeTypeRecord) = RecordEncoder $ contramap f <$> encodeTypeRecord--instance Divisible RecordEncoder where-  divide f (RecordEncoder bEncoderRecord) (RecordEncoder cEncoderRecord) =-      RecordEncoder-    $ Dhall.Map.union-      ((contramap $ fst . f) <$> bEncoderRecord)-      ((contramap $ snd . f) <$> cEncoderRecord)-  conquer = RecordEncoder mempty--{-| Specify how to encode one field of a record by supplying an explicit-    `Encoder` for that field--}-encodeFieldWith :: Text -> Encoder a -> RecordEncoder a-encodeFieldWith name encodeType = RecordEncoder $ Dhall.Map.singleton name encodeType--{-| Specify how to encode one field of a record using the default `ToDhall`-    instance for that type--}-encodeField :: ToDhall a => Text -> RecordEncoder a-encodeField name = encodeFieldWith name inject---- | Convert a `RecordEncoder` into the equivalent `Encoder`-recordEncoder :: RecordEncoder a -> Encoder a-recordEncoder (RecordEncoder encodeTypeRecord) = Encoder makeRecordLit recordType-  where-    recordType = Record $ (Core.makeRecordField . declared) <$> encodeTypeRecord-    makeRecordLit x = RecordLit $ (Core.makeRecordField . ($ x) . embed) <$> encodeTypeRecord--{-| 'UnionEncoder' allows you to build an 'Encoder' for a Dhall record.--    For example, let's take the following Haskell data type:-->>> :{-data Status = Queued Natural-            | Result Text-            | Errored Text-:}--    And assume that we have the following Dhall union that we would like to-    parse as a @Status@:--> < Result : Text-> | Queued : Natural-> | Errored : Text-> >.Result "Finish successfully"--    Our encoder has type 'Encoder' @Status@, but we can't build that out of any-    smaller encoders, as 'Encoder's cannot be combined.-    However, we can use an 'UnionEncoder' to build an 'Encoder' for @Status@:-->>> :{-injectStatus :: Encoder Status-injectStatus = adapt >$< unionEncoder-  (   encodeConstructorWith "Queued"  inject-  >|< encodeConstructorWith "Result"  inject-  >|< encodeConstructorWith "Errored" inject-  )-  where-    adapt (Queued  n) = Left n-    adapt (Result  t) = Right (Left t)-    adapt (Errored e) = Right (Right e)-:}--    Or, since we are simply using the `ToDhall` instance to inject each branch, we could write-->>> :{-injectStatus :: Encoder Status-injectStatus = adapt >$< unionEncoder-  (   encodeConstructor "Queued"-  >|< encodeConstructor "Result"-  >|< encodeConstructor "Errored"-  )-  where-    adapt (Queued  n) = Left n-    adapt (Result  t) = Right (Left t)-    adapt (Errored e) = Right (Right e)-:}---}-newtype UnionEncoder a =-  UnionEncoder-    ( Data.Functor.Product.Product-        ( Control.Applicative.Const-            ( Dhall.Map.Map-                Text-                ( Expr Src Void )-            )-        )-        ( Op (Text, Expr Src Void) )-        a-    )-  deriving (Contravariant)---- | Combines two 'UnionEncoder' values.  See 'UnionEncoder' for usage--- notes.------ Ideally, this matches 'Data.Functor.Contravariant.Divisible.chosen';--- however, this allows 'UnionEncoder' to not need a 'Divisible' instance--- itself (since no instance is possible).-(>|<) :: UnionEncoder a -> UnionEncoder b -> UnionEncoder (Either a b)-UnionEncoder (Data.Functor.Product.Pair (Control.Applicative.Const mx) (Op fx))-    >|< UnionEncoder (Data.Functor.Product.Pair (Control.Applicative.Const my) (Op fy)) =-    UnionEncoder-      ( Data.Functor.Product.Pair-          ( Control.Applicative.Const (mx <> my) )-          ( Op (either fx fy) )-      )--infixr 5 >|<---- | Convert a `UnionEncoder` into the equivalent `Encoder`-unionEncoder :: UnionEncoder a -> Encoder a-unionEncoder ( UnionEncoder ( Data.Functor.Product.Pair ( Control.Applicative.Const fields ) ( Op embedF ) ) ) =-    Encoder-      { embed = \x ->-          let (name, y) = embedF x-          in  case notEmptyRecordLit y of-                  Nothing  -> Field (Union fields') $ Core.makeFieldSelection name-                  Just val -> App (Field (Union fields') $ Core.makeFieldSelection name) val-      , declared =-          Union fields'-      }-  where-    fields' = fmap notEmptyRecord fields--{-| Specify how to encode an alternative by providing an explicit `Encoder`-    for that alternative--}-encodeConstructorWith-    :: Text-    -> Encoder a-    -> UnionEncoder a-encodeConstructorWith name encodeType = UnionEncoder $-    Data.Functor.Product.Pair-      ( Control.Applicative.Const-          ( Dhall.Map.singleton-              name-              ( declared encodeType )-          )-      )-      ( Op ( (name,) . embed encodeType )-      )--{-| Specify how to encode an alternative by using the default `ToDhall` instance-    for that type--}-encodeConstructor-    :: ToDhall a-    => Text-    -> UnionEncoder a-encodeConstructor name = encodeConstructorWith name inject+{-# LANGUAGE ApplicativeDo         #-}+{-# LANGUAGE ConstraintKinds       #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE RankNTypes            #-}+{-# LANGUAGE RecordWildCards       #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE UndecidableInstances  #-}++{-| Please read the "Dhall.Tutorial" module, which contains a tutorial explaining+    how to use the language, the compiler, and this library+-}++module Dhall+    (+    -- * Input+      input+    , inputWithSettings+    , inputFile+    , inputFileWithSettings+    , inputExpr+    , inputExprWithSettings+    , interpretExpr+    , interpretExprWithSettings+    , fromExpr+    , fromExprWithSettings+    , rootDirectory+    , sourceName+    , startingContext+    , substitutions+    , normalizer+    , newManager+    , defaultInputSettings+    , InputSettings+    , defaultEvaluateSettings+    , EvaluateSettings+    , HasEvaluateSettings(..)+    , detailed++    -- * Decoders+    , module Dhall.Marshal.Decode++    -- * Encoders+    , module Dhall.Marshal.Encode++    -- * Individual phases+    , parseWithSettings+    , resolveWithSettings+    , resolveAndStatusWithSettings+    , typecheckWithSettings+    , checkWithSettings+    , expectWithSettings+    , normalizeWithSettings++    -- * Miscellaneous+    , rawInput+    ) where++import Control.Applicative    (Alternative, empty)+import Control.Monad.Catch    (MonadThrow, throwM)+import Data.Either.Validation (Validation (..))+import Data.Void              (Void)+import Dhall.Import           (Imported (..), Status)+import Dhall.Parser           (Src (..))+import Dhall.Syntax           (Expr (..), Import)+import Dhall.TypeCheck        (DetailedTypeError (..), TypeError)+import GHC.Generics+import Lens.Micro             (Lens', lens)+import Lens.Micro.Extras      (view)+import Prelude                hiding (maybe, sequence)+import System.FilePath        (takeDirectory)++import qualified Control.Exception+import qualified Control.Monad.Trans.State.Strict as State+import qualified Data.Text.IO+import qualified Dhall.Context+import qualified Dhall.Core                       as Core+import qualified Dhall.Import+import qualified Dhall.Parser+import qualified Dhall.Pretty.Internal+import qualified Dhall.Substitution+import qualified Dhall.TypeCheck+import qualified Lens.Micro                       as Lens++import Dhall.Marshal.Decode+import Dhall.Marshal.Encode++-- | @since 1.16+data InputSettings = InputSettings+  { _rootDirectory :: FilePath+  , _sourceName :: FilePath+  , _evaluateSettings :: EvaluateSettings+  }++-- | Default input settings: resolves imports relative to @.@ (the+-- current working directory), report errors as coming from @(input)@,+-- and default evaluation settings from 'defaultEvaluateSettings'.+--+-- @since 1.16+defaultInputSettings :: InputSettings+defaultInputSettings = InputSettings+  { _rootDirectory = "."+  , _sourceName = "(input)"+  , _evaluateSettings = defaultEvaluateSettings+  }+++-- | Access the directory to resolve imports relative to.+--+-- @since 1.16+rootDirectory :: Lens' InputSettings FilePath+rootDirectory = lens _rootDirectory (\s x -> s { _rootDirectory = x })++-- | Access the name of the source to report locations from; this is+-- only used in error messages, so it's okay if this is a best guess+-- or something symbolic.+--+-- @since 1.16+sourceName :: Lens' InputSettings FilePath+sourceName = lens _sourceName (\s x -> s { _sourceName = x})++-- | @since 1.16+data EvaluateSettings = EvaluateSettings+  { _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+-- context, and no special normalizer behaviour.+--+-- @since 1.16+defaultEvaluateSettings :: EvaluateSettings+defaultEvaluateSettings = EvaluateSettings+  { _substitutions   = Dhall.Substitution.empty+  , _startingContext = Dhall.Context.empty+  , _normalizer      = Nothing+  , _newManager      = Dhall.Import.defaultNewManager+  }++-- | Access the starting context used for evaluation and type-checking.+--+-- @since 1.16+startingContext+  :: (HasEvaluateSettings s)+  => Lens' s (Dhall.Context.Context (Expr Src Void))+startingContext =+    evaluateSettings+        . lens _startingContext (\s x -> s { _startingContext = x})++-- | Access the custom substitutions.+--+-- @since 1.30+substitutions+  :: (HasEvaluateSettings s)+  => Lens' s (Dhall.Substitution.Substitutions Src Void)+substitutions =+    evaluateSettings+        . lens _substitutions (\s x -> s { _substitutions = x })++-- | Access the custom normalizer.+--+-- @since 1.16+normalizer+  :: (HasEvaluateSettings s)+  => Lens' s (Maybe (Core.ReifiedNormalizer Void))+normalizer =+    evaluateSettings+        . lens _normalizer (\s x -> s { _normalizer = x })++-- | Access the HTTP manager initializer.+--+-- @since 1.36+newManager+  :: (HasEvaluateSettings s)+  => Lens' s (IO Dhall.Import.Manager)+newManager =+    evaluateSettings+        . lens _newManager (\s x -> s { _newManager = x })++-- | @since 1.16+class HasEvaluateSettings s where+  evaluateSettings :: Lens' s EvaluateSettings++instance HasEvaluateSettings InputSettings where+  evaluateSettings =+    lens _evaluateSettings (\s x -> s { _evaluateSettings = x })++instance HasEvaluateSettings EvaluateSettings where+  evaluateSettings = id++-- | Parse an expression, using the supplied `InputSettings`+parseWithSettings :: MonadThrow m => InputSettings -> Text -> m (Expr Src Import)+parseWithSettings settings text =+    either throwM return (Dhall.Parser.exprFromText (view sourceName settings) text)++-- | Type-check an expression, using the supplied `InputSettings`+typecheckWithSettings :: MonadThrow m => InputSettings -> Expr Src Void -> m ()+typecheckWithSettings settings expression =+    either throwM (return . const ()) (Dhall.TypeCheck.typeWith (view startingContext settings) expression)++{-| Type-check an expression against a type provided as a Dhall expreession,+    using the supplied `InputSettings`+-}+checkWithSettings ::+    MonadThrow m =>+    -- | The input settings+    InputSettings ->+    -- | The expected type of the expression+    Expr Src Void ->+    -- | The expression to check+    Expr Src Void ->+    m ()+checkWithSettings settings type_ expression = do+    let suffix = Dhall.Pretty.Internal.prettyToStrictText type_++    let annotated = case expression of+            Note (Src begin end bytes) _ ->+                Note (Src begin end bytes') (Annot expression type_)+              where+                bytes' = bytes <> " : " <> suffix+            _ ->+                Annot expression type_++    typecheckWithSettings settings annotated++{-| Type-check an expression against a `Decoder`'s expected type, using the+    supplied `InputSettings`.+    This is equivalent of using the 'expected' type of a @Decoder@ as the second+    argument to 'checkWithSettings'.+-}+expectWithSettings :: MonadThrow m => InputSettings -> Decoder a -> Expr Src Void -> m ()+expectWithSettings settings Decoder{..} expression = do+    expected' <- case expected of+        Success x -> return x+        Failure e -> throwM e++    checkWithSettings settings expected' expression++{-| Resolve an expression, using the supplied `InputSettings`++    Note that this also applies any substitutions specified in the+    `InputSettings`+-}+resolveWithSettings :: InputSettings -> Expr Src Import -> IO (Expr Src Void)+resolveWithSettings settings expression =+    fst <$> resolveAndStatusWithSettings settings expression++-- | A version of 'resolveWithSettings' that also returns the import 'Status'+-- together with the resolved expression.+resolveAndStatusWithSettings+    :: InputSettings+    -> Expr Src Import+    -> IO (Expr Src Void, Status)+resolveAndStatusWithSettings settings expression = do+    let InputSettings{..} = settings++    let EvaluateSettings{..} = _evaluateSettings++    let transform =+               Lens.set Dhall.Import.substitutions   _substitutions+            .  Lens.set Dhall.Import.normalizer      _normalizer+            .  Lens.set Dhall.Import.startingContext _startingContext++    let status = transform (Dhall.Import.emptyStatusWithManager _newManager _rootDirectory)++    (resolved, status') <- State.runStateT (Dhall.Import.loadWith expression) status++    let substituted = Dhall.Substitution.substitute resolved (view substitutions settings)++    pure (substituted, status')++-- | Normalize an expression, using the supplied `InputSettings`+normalizeWithSettings :: InputSettings -> Expr Src Void -> Expr Src Void+normalizeWithSettings settings =+    Core.normalizeWith (view normalizer settings)++{-| Type-check and evaluate a Dhall program, decoding the result into Haskell++    The first argument determines the type of value that you decode:++>>> input integer "+2"+2+>>> input (vector double) "[1.0, 2.0]"+[1.0,2.0]++    Use `auto` to automatically select which type to decode based on the+    inferred return type:++>>> input auto "True" :: IO Bool+True++    This uses the settings from 'defaultInputSettings'.+-}+input+    :: Decoder a+    -- ^ The decoder for the Dhall value+    -> Text+    -- ^ The Dhall program+    -> IO a+    -- ^ The decoded value in Haskell+input =+  inputWithSettings defaultInputSettings++{-| Extend 'input' with a root directory to resolve imports relative+    to, a file to mention in errors as the source, a custom typing+    context, and a custom normalization process.++@since 1.16+-}+inputWithSettings+    :: InputSettings+    -> Decoder a+    -- ^ The decoder for the Dhall value+    -> Text+    -- ^ The Dhall program+    -> IO a+    -- ^ The decoded value in Haskell+inputWithSettings settings decoder@Decoder{..} text = do+    parsed <- parseWithSettings settings text++    resolved <- resolveWithSettings settings parsed++    expectWithSettings settings decoder resolved++    let normalized = normalizeWithSettings settings resolved++    case extract normalized of+        Success x -> return x+        Failure e -> Control.Exception.throwIO e++{-| Type-check and evaluate a Dhall program that is read from the+    file-system.++    This uses the settings from 'defaultEvaluateSettings'.++    @since 1.16+-}+inputFile+  :: Decoder a+  -- ^ The decoder for the Dhall value+  -> FilePath+  -- ^ The path to the Dhall program.+  -> IO a+  -- ^ The decoded value in Haskell.+inputFile =+  inputFileWithSettings defaultEvaluateSettings++{-| Extend 'inputFile' with a custom typing context and a custom+    normalization process.++@since 1.16+-}+inputFileWithSettings+  :: EvaluateSettings+  -> Decoder a+  -- ^ The decoder for the Dhall value+  -> FilePath+  -- ^ The path to the Dhall program.+  -> IO a+  -- ^ The decoded value in Haskell.+inputFileWithSettings settings ty path = do+  text <- Data.Text.IO.readFile path+  let inputSettings = InputSettings+        { _rootDirectory = takeDirectory path+        , _sourceName = path+        , _evaluateSettings = settings+        }+  inputWithSettings inputSettings ty text++{-| Similar to `input`, but without interpreting the Dhall `Expr` into a Haskell+    type.++    Uses the settings from 'defaultInputSettings'.+-}+inputExpr+    :: Text+    -- ^ The Dhall program+    -> IO (Expr Src Void)+    -- ^ The fully normalized AST+inputExpr =+  inputExprWithSettings defaultInputSettings++{-| Extend 'inputExpr' with a root directory to resolve imports relative+    to, a file to mention in errors as the source, a custom typing+    context, and a custom normalization process.++@since 1.16+-}+inputExprWithSettings+    :: InputSettings+    -> Text+    -- ^ The Dhall program+    -> IO (Expr Src Void)+    -- ^ The fully normalized AST+inputExprWithSettings settings text = do+    parsed <- parseWithSettings settings text++    resolved <- resolveWithSettings settings parsed++    _ <- typecheckWithSettings settings resolved++    pure (Core.normalizeWith (view normalizer settings) resolved)++{-| Interpret a Dhall Expression++    This takes care of import resolution, type-checking, and normalization+-}+interpretExpr :: Expr Src Import -> IO (Expr Src Void)+interpretExpr = interpretExprWithSettings defaultInputSettings++-- | Like `interpretExpr`, but customizable using `InputSettings`+interpretExprWithSettings+    :: InputSettings -> Expr Src Import -> IO (Expr Src Void)+interpretExprWithSettings settings parsed = do+    resolved <- resolveWithSettings settings parsed++    typecheckWithSettings settings resolved++    pure (Core.normalizeWith (view normalizer settings) resolved)++{- | Decode a Dhall expression++    This takes care of import resolution, type-checking and normalization+-}+fromExpr :: Decoder a -> Expr Src Import -> IO a+fromExpr = fromExprWithSettings defaultInputSettings++-- | Like `fromExpr`, but customizable using `InputSettings`+fromExprWithSettings :: InputSettings -> Decoder a -> Expr Src Import -> IO a+fromExprWithSettings settings decoder@Decoder{..} expression = do+    resolved <- resolveWithSettings settings expression++    expectWithSettings settings decoder resolved++    let normalized = Core.normalizeWith (view normalizer settings) resolved++    case extract normalized of+        Success x -> return x+        Failure e -> Control.Exception.throwIO e++-- | Use this function to extract Haskell values directly from Dhall AST.+--   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+--   a much better user experience.+rawInput+    :: Alternative f+    => Decoder a+    -- ^ The decoder for the Dhall value+    -> Expr s Void+    -- ^ a closed form Dhall program, which evaluates to the expected type+    -> f a+    -- ^ The decoded value in Haskell+rawInput (Decoder {..}) expr =+    case extract (Core.normalize expr) of+        Success x  -> pure x+        Failure _e -> empty++{-| Use this to provide more detailed error messages++>> input auto "True" :: IO Integer+> *** Exception: Error: Expression doesn't match annotation+>+> True : Integer+>+> (input):1:1++>> detailed (input auto "True") :: IO Integer+> *** Exception: Error: Expression doesn't match annotation+>+> Explanation: You can annotate an expression with its type or kind using the+> ❰:❱ symbol, like this:+>+>+>     ┌───────┐+>     │ x : t │  ❰x❱ is an expression and ❰t❱ is the annotated type or kind of ❰x❱+>     └───────┘+>+> The type checker verifies that the expression's type or kind matches the+> provided annotation+>+> For example, all of the following are valid annotations that the type checker+> accepts:+>+>+>     ┌─────────────┐+>     │ 1 : Natural │  ❰1❱ is an expression that has type ❰Natural❱, so the type+>     └─────────────┘  checker accepts the annotation+>+>+>     ┌───────────────────────┐+>     │ Natural/even 2 : Bool │  ❰Natural/even 2❱ has type ❰Bool❱, so the type+>     └───────────────────────┘  checker accepts the annotation+>+>+>     ┌────────────────────┐+>     │ List : Type → Type │  ❰List❱ is an expression that has kind ❰Type → Type❱,+>     └────────────────────┘  so the type checker accepts the annotation+>+>+>     ┌──────────────────┐+>     │ List Text : Type │  ❰List Text❱ is an expression that has kind ❰Type❱, so+>     └──────────────────┘  the type checker accepts the annotation+>+>+> However, the following annotations are not valid and the type checker will+> reject them:+>+>+>     ┌──────────┐+>     │ 1 : Text │  The type checker rejects this because ❰1❱ does not have type+>     └──────────┘  ❰Text❱+>+>+>     ┌─────────────┐+>     │ List : Type │  ❰List❱ does not have kind ❰Type❱+>     └─────────────┘+>+>+> You or the interpreter annotated this expression:+>+> ↳ True+>+> ... with this type or kind:+>+> ↳ Integer+>+> ... but the inferred type or kind of the expression is actually:+>+> ↳ Bool+>+> Some common reasons why you might get this error:+>+> ● The Haskell Dhall interpreter implicitly inserts a top-level annotation+>   matching the expected type+>+>   For example, if you run the following Haskell code:+>+>+>     ┌───────────────────────────────┐+>     │ >>> input auto "1" :: IO Text │+>     └───────────────────────────────┘+>+>+>   ... then the interpreter will actually type check the following annotated+>   expression:+>+>+>     ┌──────────┐+>     │ 1 : Text │+>     └──────────┘+>+>+>   ... and then type-checking will fail+>+> ────────────────────────────────────────────────────────────────────────────────+>+> True : Integer+>+> (input):1:1++-}+detailed :: IO a -> IO a+detailed =+    Control.Exception.handle handler1 . Control.Exception.handle handler0+  where+    handler0 :: Imported (TypeError Src Void) -> IO a+    handler0 (Imported ps e) =+        Control.Exception.throwIO (Imported ps (DetailedTypeError e))++    handler1 :: TypeError Src Void -> IO a+    handler1 e = Control.Exception.throwIO (DetailedTypeError e)
src/Dhall/Binary.hs view
@@ -13,15 +13,11 @@ -}  module Dhall.Binary-    ( -- * Standard versions-      StandardVersion(..)-    , renderStandardVersion--    -- * Encoding and decoding-    , encodeExpression+    ( -- * Encoding and decoding+      encodeExpression     , decodeExpression -    -- * Exceptions+      -- * Exceptions     , DecodingFailure(..)     ) where @@ -51,61 +47,33 @@     , Scheme (..)     , URL (..)     , Var (..)+    , WithComponent (..)     )  import Data.Foldable (toList)-import Data.Text     (Text)+import Data.Ratio    ((%)) import Data.Void     (Void, absurd) import GHC.Float     (double2Float, float2Double) import Numeric.Half  (fromHalf, toHalf)+import Prelude       hiding (exponent)  import qualified Codec.CBOR.ByteArray import qualified Codec.CBOR.Decoding   as Decoding import qualified Codec.CBOR.Encoding   as Encoding import qualified Codec.CBOR.Read       as Read import qualified Codec.Serialise       as Serialise-import qualified Data.ByteArray 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 Data.Time             as Time import qualified Dhall.Crypto import qualified Dhall.Map-import qualified Dhall.Set import qualified Dhall.Syntax          as Syntax import qualified Text.Printf           as Printf -{-| Supported version strings--    This exists primarily for backwards compatibility for expressions encoded-    before Dhall removed version tags from the binary encoding--}-data StandardVersion-    = NoVersion-    -- ^ No version string-    | V_5_0_0-    -- ^ Version "5.0.0"-    | V_4_0_0-    -- ^ Version "4.0.0"-    | V_3_0_0-    -- ^ Version "3.0.0"-    | V_2_0_0-    -- ^ Version "2.0.0"-    | V_1_0_0-    -- ^ Version "1.0.0"-    deriving (Enum, Bounded)---- | Render a `StandardVersion` as `Data.Text.Text`-renderStandardVersion :: StandardVersion -> Text-renderStandardVersion NoVersion = "none"-renderStandardVersion V_1_0_0   = "1.0.0"-renderStandardVersion V_2_0_0   = "2.0.0"-renderStandardVersion V_3_0_0   = "3.0.0"-renderStandardVersion V_4_0_0   = "4.0.0"-renderStandardVersion V_5_0_0   = "5.0.0"- {-| Convert a function applied to multiple arguments to the base function and     the list of arguments -}@@ -168,20 +136,26 @@                  case Data.ByteString.Short.length sb of                     4  | sb == "Bool"              -> return Bool+                       | sb == "Date"              -> return Date                        | sb == "List"              -> return List                        | sb == "None"              -> return None                        | sb == "Text"              -> return Text+                       | sb == "Time"              -> return Time                        | sb == "Type"              -> return (Const Type)                        | sb == "Kind"              -> return (Const Kind)                        | sb == "Sort"              -> return (Const Sort)+                    5  | sb == "Bytes"             -> return Bytes                     6  | sb == "Double"            -> return Double                     7  | sb == "Integer"           -> return Integer                        | sb == "Natural"           -> return Natural                     8  | sb == "Optional"          -> return Optional-                    9  | sb == "List/fold"         -> return ListFold+                       | sb == "TimeZone"          -> return TimeZone+                    9  | sb == "Date/show"         -> return DateShow+                       | sb == "List/fold"         -> return ListFold                        | sb == "List/head"         -> return ListHead                        | sb == "List/last"         -> return ListLast                        | sb == "Text/show"         -> return TextShow+                       | sb == "Time/show"         -> return TimeShow                     10 | sb == "List/build"        -> return ListBuild                     11 | sb == "Double/show"       -> return DoubleShow                        | sb == "List/length"       -> return ListLength@@ -195,6 +169,7 @@                        | sb == "Text/replace"      -> return TextReplace                     13 | sb == "Integer/clamp"     -> return IntegerClamp                        | sb == "Natural/build"     -> return NaturalBuild+                       | sb == "TimeZone/show"     -> return TimeZoneShow                     14 | sb == "Integer/negate"    -> return IntegerNegate                        | sb == "Natural/isZero"    -> return NaturalIsZero                     16 | sb == "Integer/toDouble"  -> return IntegerToDouble@@ -261,7 +236,7 @@                                          b <- go -                                        return (Lam (Syntax.makeFunctionBinding "_" _A) b)+                                        return (Lam mempty (Syntax.makeFunctionBinding "_" _A) b)                                      4 -> do                                         x <- Decoding.decodeString@@ -274,7 +249,7 @@                                          b <- go -                                        return (Lam (Syntax.makeFunctionBinding x _A) b)+                                        return (Lam mempty (Syntax.makeFunctionBinding x _A) b)                                      _ ->                                         die ("Incorrect number of tokens used to encode a λ expression: " <> show len)@@ -286,7 +261,7 @@                                          _B <- go -                                        return (Pi "_" _A _B)+                                        return (Pi mempty "_" _A _B)                                      4 -> do                                         x <- Decoding.decodeString@@ -299,7 +274,7 @@                                          _B <- go -                                        return (Pi x _A _B)+                                        return (Pi mempty x _A _B)                                      _ ->                                         die ("Incorrect number of tokens used to encode a ∀ expression: " <> show len)@@ -316,11 +291,11 @@                                     5  -> return NaturalTimes                                     6  -> return TextAppend                                     7  -> return ListAppend-                                    8  -> return (Combine Nothing)-                                    9  -> return (Prefer PreferFromSource)-                                    10 -> return CombineTypes+                                    8  -> return (Combine mempty Nothing)+                                    9  -> return (Prefer mempty PreferFromSource)+                                    10 -> return (CombineTypes mempty)                                     11 -> return ImportAlt-                                    12 -> return Equivalent+                                    12 -> return (Equivalent mempty)                                     13 -> return RecordCompletion                                     _  -> die ("Unrecognized operator code: " <> show opcode) @@ -415,7 +390,7 @@                                              TypeString -> do                                                 x <- Decoding.decodeString-                                                return (Left (Dhall.Set.fromList [x]))+                                                return (Left [x])                                              _ ->                                                 die ("Unexpected token type for projection: " <> show tokenType₂)@@ -423,7 +398,7 @@                                     _ -> do                                         xs <- replicateDecoder (len - 2) Decoding.decodeString -                                        return (Left (Dhall.Set.fromList xs))+                                        return (Left xs)                                  return (Project t xs) @@ -589,8 +564,19 @@                                  n <- Decoding.decodeListLen -                                ks₀ <- replicateDecoder n Decoding.decodeString+                                let decodeWithComponent = do+                                        tokenType₂ <- Decoding.peekTokenType+                                        case tokenType₂ of+                                            TypeString -> do+                                                fmap WithLabel Decoding.decodeString+                                            _ -> do+                                                m <- Decoding.decodeInt +                                                case m of+                                                    0 -> return WithQuestion+                                                    _ -> die ("Unexpected integer encoding a with expression: " <> show n)+                                ks₀ <- replicateDecoder n decodeWithComponent+                                 ks₁ <- case NonEmpty.nonEmpty ks₀ of                                     Nothing ->                                         die "0 field labels in decoded with expression"@@ -601,6 +587,82 @@                                  return (With l ks₁ r) +                            30 -> do+                                _YYYY <- Decoding.decodeInt+                                _MM   <- Decoding.decodeInt+                                _HH   <- Decoding.decodeInt++                                case Time.fromGregorianValid (fromIntegral _YYYY) _MM _HH of+                                    Nothing ->+                                        die "Invalid date"+                                    Just day ->+                                        return (DateLiteral day)+                            31 -> do+                                hh <- Decoding.decodeInt+                                mm <- Decoding.decodeInt+                                tag₂ <- Decoding.decodeTag++                                case tag₂ of+                                    4 -> do+                                        return ()+                                    _ -> do+                                        die ("Unexpected tag for decimal fraction: " <> show tag)+                                n <- Decoding.decodeListLen++                                case n of+                                    2 -> do+                                        return ()+                                    _ -> do+                                        die ("Invalid list length for decimal fraction: " <> show n)++                                exponent <- Decoding.decodeInt++                                tokenType₂ <- Decoding.peekTokenType++                                mantissa <- case tokenType₂ of+                                    TypeUInt -> do+                                        fromIntegral <$> Decoding.decodeWord++                                    TypeUInt64 -> do+                                        fromIntegral <$> Decoding.decodeWord64++                                    TypeNInt -> do+                                        !i <- fromIntegral <$> Decoding.decodeNegWord++                                        return (-1 - i)++                                    TypeNInt64 -> do+                                        !i <- fromIntegral <$> Decoding.decodeNegWord64++                                        return (-1 - i)+                                    TypeInteger -> do+                                        Decoding.decodeInteger+                                    _ ->+                                        die ("Unexpected token type for mantissa: " <> show tokenType₂)+                                let precision = fromIntegral (negate exponent)++                                let ss = fromRational (mantissa % (10 ^ precision))++                                return (TimeLiteral (Time.TimeOfDay hh mm ss) precision)+                            32 -> do+                                b   <- Decoding.decodeBool+                                _HH <- Decoding.decodeInt+                                _MM <- Decoding.decodeInt++                                let sign = if b then id else negate++                                let minutes = sign (_HH * 60 + _MM)++                                return (TimeZoneLiteral (Time.TimeZone minutes False ""))++                            33 -> do+                                b <- Decoding.decodeBytes++                                return (BytesLit b)++                            34 -> do+                                t <- go+                                return (ShowConstructor t)                             _ ->                                 die ("Unexpected tag: " <> show tag) @@ -685,6 +747,9 @@         Bool ->             Encoding.encodeUtf8ByteArray "Bool" +        Bytes ->+            Encoding.encodeUtf8ByteArray "Bytes"+         Optional ->             Encoding.encodeUtf8ByteArray "Optional" @@ -709,6 +774,24 @@         TextShow ->             Encoding.encodeUtf8ByteArray "Text/show" +        Date ->+            Encoding.encodeUtf8ByteArray "Date"++        DateShow ->+            Encoding.encodeUtf8ByteArray "Date/show"++        Time ->+            Encoding.encodeUtf8ByteArray "Time"++        TimeShow ->+            Encoding.encodeUtf8ByteArray "Time/show"++        TimeZone ->+            Encoding.encodeUtf8ByteArray "TimeZone"++        TimeZoneShow ->+            Encoding.encodeUtf8ByteArray "TimeZone/show"+         List ->             Encoding.encodeUtf8ByteArray "List" @@ -731,26 +814,26 @@           where             (function, arguments) = unApply a -        Lam (FunctionBinding { functionBindingVariable = "_", functionBindingAnnotation = _A }) b ->+        Lam _ (FunctionBinding { functionBindingVariable = "_", functionBindingAnnotation = _A }) b ->             encodeList3                 (Encoding.encodeInt 1)                 (go _A)                 (go b) -        Lam (FunctionBinding { functionBindingVariable = x, functionBindingAnnotation = _A }) b ->+        Lam _ (FunctionBinding { functionBindingVariable = x, functionBindingAnnotation = _A }) b ->             encodeList4                 (Encoding.encodeInt 1)                 (Encoding.encodeString x)                 (go _A)                 (go b) -        Pi "_" _A _B ->+        Pi _ "_" _A _B ->             encodeList3                 (Encoding.encodeInt 2)                 (go _A)                 (go _B) -        Pi x _A _B ->+        Pi _ x _A _B ->             encodeList4                 (Encoding.encodeInt 2)                 (Encoding.encodeString x)@@ -769,6 +852,11 @@         BoolNE l r ->             encodeOperator 3 l r +        BytesLit b ->+            encodeList2+                (Encoding.encodeInt 33)+                (Encoding.encodeBytes b)+         NaturalPlus l r ->             encodeOperator 4 l r @@ -781,19 +869,19 @@         ListAppend l r ->             encodeOperator 7 l r -        Combine _ l r ->+        Combine _ _ l r ->             encodeOperator 8 l r -        Prefer _ l r ->+        Prefer _ _ l r ->             encodeOperator 9 l r -        CombineTypes l r ->+        CombineTypes _ l r ->             encodeOperator 10 l r          ImportAlt l r ->             encodeOperator 11 l r -        Equivalent l r ->+        Equivalent _ l r ->             encodeOperator 12 l r          RecordCompletion l r ->@@ -852,10 +940,10 @@          Project t (Left xs) ->             encodeListN-                (2 + Dhall.Set.size xs)+                (2 + length xs)                 ( Encoding.encodeInt 10                 : go t-                : map Encoding.encodeString (Dhall.Set.toList xs)+                : map Encoding.encodeString xs                 )          Project t (Right _T) ->@@ -968,9 +1056,60 @@             encodeList4                 (Encoding.encodeInt 29)                 (go l)-                (encodeList (fmap Encoding.encodeString ks))+                (encodeList (fmap encodeWithComponent ks))                 (go r)+          where+            encodeWithComponent  WithQuestion  = Encoding.encodeInt 0+            encodeWithComponent (WithLabel k ) = Encoding.encodeString k +        DateLiteral day ->+            encodeList4+                (Encoding.encodeInt 30)+                (Encoding.encodeInt (fromInteger _YYYY))+                (Encoding.encodeInt _MM)+                (Encoding.encodeInt _DD)+          where+            (_YYYY, _MM, _DD) = Time.toGregorian day++        TimeLiteral (Time.TimeOfDay hh mm ss) precision ->+            encodeList4+                (Encoding.encodeInt 31)+                (Encoding.encodeInt hh)+                (Encoding.encodeInt mm)+                (   Encoding.encodeTag 4+                <>  encodeList2+                        (Encoding.encodeInt exponent)+                        encodedMantissa+                )+          where+            exponent = negate (fromIntegral precision)++            mantissa :: Integer+            mantissa = truncate (ss * 10 ^ precision)++            encodedMantissa+                |  fromIntegral (minBound :: Int) <= mantissa+                && mantissa <= fromIntegral (maxBound :: Int) =+                    Encoding.encodeInt (fromInteger mantissa)+                | otherwise =+                    Encoding.encodeInteger mantissa++        TimeZoneLiteral (Time.TimeZone minutes _ _) ->+            encodeList4+                (Encoding.encodeInt 32)+                (Encoding.encodeBool sign)+                (Encoding.encodeInt _HH)+                (Encoding.encodeInt _MM)+          where+            sign = 0 <= minutes++            (_HH, _MM) = abs minutes `divMod` 60++        ShowConstructor t ->+            encodeList2+                (Encoding.encodeInt 34)+                (go t)+         Note _ b ->             go b @@ -1045,6 +1184,7 @@         0 -> return Code         1 -> return RawText         2 -> return Location+        3 -> return RawBytes         _ -> die ("Unexpected code for import mode: " <> show m)      let remote scheme = do@@ -1181,9 +1321,13 @@                 Encoding.encodeNull              Just digest ->-                Encoding.encodeBytes ("\x12\x20" <> Data.ByteArray.convert digest)+                Encoding.encodeBytes ("\x12\x20" <> Dhall.Crypto.unSHA256Digest digest) -        m = Encoding.encodeInt (case importMode of Code -> 0; RawText -> 1; Location -> 2;)+        m = Encoding.encodeInt (case importMode of+            Code -> 0+            RawText -> 1+            Location -> 2+            RawBytes -> 3 )      Import{..} = import_ 
src/Dhall/Core.hs view
@@ -31,6 +31,7 @@     , makeFunctionBinding     , FieldSelection (..)     , makeFieldSelection+    , WithComponent (..)     , Expr(..)      -- * Normalization@@ -56,6 +57,7 @@      -- * Optics     , subExpressions+    , subExpressionsWith     , chunkExprs     , bindingExprs     , recordFieldExprs@@ -75,24 +77,22 @@     , Eval.textShow     , censorExpression     , censorText-    , Syntax.desugarWith     ) where -import Control.Exception         (Exception)-import Control.Monad.IO.Class    (MonadIO (..))-import Data.Text                 (Text)-import Data.Text.Prettyprint.Doc (Pretty)+import Control.Exception      (Exception)+import Control.Monad.IO.Class (MonadIO (..))+import Data.Text              (Text) import Dhall.Normalize import Dhall.Pretty.Internal-import Dhall.Src                 (Src (..))+import Dhall.Src              (Src (..)) import Dhall.Syntax-import Instances.TH.Lift         ()-import Lens.Family               (over)+import Instances.TH.Lift      ()+import Lens.Micro             (over)+import Prettyprinter          (Pretty)  import qualified Control.Exception import qualified Data.Text import qualified Dhall.Eval        as Eval-import qualified Dhall.Syntax      as Syntax  -- | Pretty-print a value pretty :: Pretty a => a -> Text@@ -142,6 +142,7 @@ throws :: (Exception e, MonadIO io) => Either e a -> io a throws (Left  e) = liftIO (Control.Exception.throwIO e) throws (Right r) = return r+{-# INLINABLE throws #-}  {- $setup >>> import qualified Codec.Serialise
src/Dhall/Deriving.hs view
@@ -1,7 +1,6 @@ {-# LANGUAGE AllowAmbiguousTypes  #-} {-# LANGUAGE DataKinds            #-} {-# LANGUAGE FlexibleContexts     #-}-{-# LANGUAGE KindSignatures       #-} {-# LANGUAGE PolyKinds            #-} {-# LANGUAGE ScopedTypeVariables  #-} {-# LANGUAGE TypeApplications     #-}
src/Dhall/Diff.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards   #-}+{-# LANGUAGE TypeApplications  #-} {-# LANGUAGE ViewPatterns      #-}  {-| This module provides functionality for concisely displaying the difference@@ -16,17 +17,16 @@     , diff     ) where -import Data.Foldable             (fold, toList)-import Data.List.NonEmpty        (NonEmpty (..))-import Data.Monoid               (Any (..))-import Data.Sequence             (Seq)-import Data.String               (IsString (..))-import Data.Text                 (Text)-import Data.Text.Prettyprint.Doc (Doc, Pretty)-import Data.Void                 (Void)-import Dhall.Map                 (Map)-import Dhall.Pretty.Internal     (Ann)-import Dhall.Set                 (Set)+import Data.ByteString       (ByteString)+import Data.Foldable         (fold, toList)+import Data.List.NonEmpty    (NonEmpty (..))+import Data.Monoid           (Any (..))+import Data.Sequence         (Seq)+import Data.String           (IsString (..))+import Data.Text             (Text)+import Data.Void             (Void)+import Dhall.Map             (Map)+import Dhall.Pretty.Internal (Ann) import Dhall.Syntax     ( Binding (..)     , Chunks (..)@@ -36,19 +36,21 @@     , FunctionBinding (..)     , RecordField (..)     , Var (..)+    , WithComponent (..)     )-import Numeric.Natural           (Natural)+import Numeric.Natural       (Natural)+import Prettyprinter         (Doc, Pretty) -import qualified Data.Algorithm.Diff       as Algo.Diff+import qualified Data.Algorithm.Diff   as Algo.Diff import qualified Data.List.NonEmpty import qualified Data.Set import qualified Data.Text-import qualified Data.Text.Prettyprint.Doc as Pretty+import qualified Data.Time             as Time import qualified Dhall.Map-import qualified Dhall.Normalize           as Normalize-import qualified Dhall.Pretty.Internal     as Internal-import qualified Dhall.Set-import qualified Dhall.Syntax              as Syntax+import qualified Dhall.Normalize       as Normalize+import qualified Dhall.Pretty.Internal as Internal+import qualified Dhall.Syntax          as Syntax+import qualified Prettyprinter         as Pretty  {-| This type is a `Doc` enriched with a `same` flag to efficiently track if     any difference was detected@@ -123,8 +125,8 @@ equals :: Diff equals = token Internal.equals -forall :: Diff-forall = token (Internal.forall Internal.Unicode)+forall_ :: Diff+forall_ = token (Internal.forall_ Internal.Unicode)  lambda :: Diff lambda = token (Internal.lambda Internal.Unicode)@@ -174,20 +176,21 @@ diffLabel :: Text -> Text -> Diff diffLabel = diffPrimitive (token . Internal.prettyLabel) -diffLabels :: Set Text -> Set Text -> Diff+diffLabels :: [Text] -> [Text] -> Diff diffLabels ksL ksR =     braced (diffFieldNames <> (if anyEqual then [ ignore ] else []))   where-    extraL = Dhall.Set.difference ksL ksR-    extraR = Dhall.Set.difference ksR ksL+    setL = Data.Set.fromList ksL+    setR = Data.Set.fromList ksR +    extraL = Data.Set.difference setL setR+    extraR = Data.Set.difference setR setL+     diffFieldNames = foldMap (adapt minus) extraL <> foldMap (adapt plus) extraR       where         adapt sign key = [ sign (token (Internal.prettyLabel key)) ] -    anyEqual = not (Data.Set.null (Data.Set.intersection-                                   (Dhall.Set.toSet ksL)-                                   (Dhall.Set.toSet ksR)))+    anyEqual = not (Data.Set.null (Data.Set.intersection setL setR))  diffNatural :: Natural -> Natural -> Diff diffNatural = diffPrimitive (token . Internal.prettyNatural)@@ -195,6 +198,22 @@ diffDouble :: DhallDouble -> DhallDouble -> Diff diffDouble = diffPrimitive (token . Internal.prettyDouble . getDhallDouble) +diffDateLiteral :: Time.Day -> Time.Day -> Diff+diffDateLiteral =+    diffPrimitive (token . Internal.prettyExpr @(Expr Void Void) . DateLiteral)++diffTimeLiteral :: Time.TimeOfDay -> Word -> Time.TimeOfDay -> Word -> Diff+diffTimeLiteral tL pL tR pR =+    diffPrimitive+        (token . Internal.prettyExpr @(Expr Void Void) . uncurry TimeLiteral)+        (tL, pL)+        (tR, pR)++diffTimeZoneLiteral :: Time.TimeZone -> Time.TimeZone -> Diff+diffTimeZoneLiteral =+    diffPrimitive+        (token . Internal.prettyExpr @(Expr Void Void) . TimeZoneLiteral)+ diffConst :: Const -> Const -> Diff diffConst = diffPrimitive (token . Internal.prettyConst) @@ -357,7 +376,7 @@      diffTextSkeleton = difference textSkeleton textSkeleton -    chunks = zipWith chunkDiff (toEitherList cL) (toEitherList cR) +    chunks = zipWith chunkDiff (toEitherList cL) (toEitherList cR)      chunkDiff a b =       case (a, b) of@@ -365,6 +384,10 @@         (Right x, Right y) -> diff x y         _                  -> diffTextSkeleton +diffBytes :: ByteString -> ByteString -> Diff+diffBytes l r =+    "0x" <> diffText (Internal.prettyBase16 l) (Internal.prettyBase16 r)+ diffList     :: (Eq a, Pretty a)     => Seq (Expr Void a) -> Seq (Expr Void a) -> Diff@@ -514,6 +537,10 @@     <>  keyword "else"     <>  " "     <>  ignore+skeleton (BytesLit {}) =+        "0x\""+    <>  ignore+    <>  "\"" skeleton (NaturalPlus {}) =         ignore     <>  " "@@ -619,6 +646,10 @@         keyword "toMap"     <>  " "     <>  ignore+skeleton (ShowConstructor {}) =+        keyword "showConstructor"+    <>  " "+    <>  ignore skeleton (Field {}) =         ignore     <>  dot@@ -648,8 +679,8 @@     enclosed' "  " (rarrow <> " ") (docs l r)   where     docs-        (Lam (FunctionBinding { functionBindingVariable = aL, functionBindingAnnotation = bL }) cL)-        (Lam (FunctionBinding { functionBindingVariable = aR, functionBindingAnnotation = bR }) cR) =+        (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@@ -708,14 +739,14 @@ diff l@(Pi {}) r@(Pi {}) =     enclosed' "  " (rarrow <> " ") (docs l r)   where-    docs (Pi aL bL cL) (Pi aR bR cR) =+    docs (Pi _ aL bL cL) (Pi _ aR bR cR) =         Data.List.NonEmpty.cons (align doc) (docs cL cR)       where         doc | same docA && same docB = ignore             | same docA =                 format mempty docB             | otherwise =-                    forall+                    forall_                 <>  lparen                 <>  format " " docA                 <>  colon@@ -766,6 +797,15 @@     mismatch l r diffAnnotatedExpression l r@(ToMap {}) =     mismatch l r+diffAnnotatedExpression (ShowConstructor aL) (ShowConstructor aR) = align doc+  where+    doc =   keyword "showConstructor"+        <>  " "+        <>  format " " (diffWithExpression aL aR)+diffAnnotatedExpression l@(ShowConstructor {}) r =+    mismatch l r+diffAnnotatedExpression l r@(ShowConstructor {}) =+    mismatch l r diffAnnotatedExpression (ListLit aL@(Just _) bL) (ListLit aR bR) = align doc   where     doc =   format " " (diffList bL bR)@@ -902,7 +942,7 @@ diffCombineExpression l@(Combine {}) r@(Combine {}) =     enclosed' "  " (operator "∧" <> " ") (docs l r)   where-    docs (Combine _ aL bL) (Combine _ aR bR) =+    docs (Combine _ _ aL bL) (Combine _ _ aR bR) =         Data.List.NonEmpty.cons (diffPreferExpression aL aR) (docs bL bR)     docs aL aR =         pure (diffPreferExpression aL aR)@@ -917,7 +957,7 @@ diffPreferExpression l@(Prefer {}) r@(Prefer {}) =     enclosed' "  " (operator "⫽" <> " ") (docs l r)   where-    docs (Prefer _ aL bL) (Prefer _ aR bR) =+    docs (Prefer _ _ aL bL) (Prefer _ _ aR bR) =         Data.List.NonEmpty.cons (diffCombineTypesExpression aL aR) (docs bL bR)     docs aL aR =         pure (diffCombineTypesExpression aL aR)@@ -932,7 +972,7 @@ diffCombineTypesExpression l@(CombineTypes {}) r@(CombineTypes {}) =     enclosed' "  " (operator "*" <> " ") (docs l r)   where-    docs (CombineTypes aL bL) (CombineTypes aR bR) =+    docs (CombineTypes _ aL bL) (CombineTypes _ aR bR) =         Data.List.NonEmpty.cons (diffTimesExpression aL aR) (docs bL bR)     docs aL aR =         pure (diffTimesExpression aL aR)@@ -993,7 +1033,7 @@ diffEquivalentExpression l@(Equivalent {}) r@(Equivalent {}) =     enclosed' "  " (operator "≡" <> " ") (docs l r)   where-    docs (Equivalent aL bL) (Equivalent aR bR) =+    docs (Equivalent _ aL bL) (Equivalent _ aR bR) =         Data.List.NonEmpty.cons (diffApplicationExpression aL aR) (docs bL bR)     docs aL aR =         pure (diffApplicationExpression aL aR)@@ -1037,12 +1077,15 @@         (   format " " (diffImportExpression eL eR)         <>  "with "         <>  align-            (   format " " (diffPath ksL ksR)+            (   format " " (diffPath (fmap toText ksL) (fmap toText ksR))             <>  "= "             <>  diffOperatorExpression vL vR             )         )   where+    toText  WithQuestion  = "?"+    toText (WithLabel k ) = k+     diffPath (kL :| []) (kR :| []) =         diffLabel kL kR     diffPath (kL₀ :| kL₁ : ksL') (kR₀ :| kR₁ : ksR') =@@ -1135,6 +1178,18 @@     mismatch l r diffPrimitiveExpression l r@Bool =     mismatch l r+diffPrimitiveExpression Bytes Bytes =+    "…"+diffPrimitiveExpression l@Bytes r =+    mismatch l r+diffPrimitiveExpression l r@Bytes =+    mismatch l r+diffPrimitiveExpression (BytesLit l) (BytesLit r) =+    diffBytes l r+diffPrimitiveExpression l@(BytesLit {}) r =+    mismatch l r+diffPrimitiveExpression l r@(BytesLit {}) =+    mismatch l r diffPrimitiveExpression Natural Natural =     "…" diffPrimitiveExpression l@Natural r =@@ -1249,6 +1304,42 @@     mismatch l r diffPrimitiveExpression l r@TextShow =     mismatch l r+diffPrimitiveExpression Date Date =+    "…"+diffPrimitiveExpression l r@Date =+    mismatch l r+diffPrimitiveExpression l@Date r=+    mismatch l r+diffPrimitiveExpression DateShow DateShow =+    "…"+diffPrimitiveExpression l r@DateShow =+    mismatch l r+diffPrimitiveExpression l@DateShow r=+    mismatch l r+diffPrimitiveExpression Time Time =+    "…"+diffPrimitiveExpression l r@Time =+    mismatch l r+diffPrimitiveExpression l@Time r=+    mismatch l r+diffPrimitiveExpression TimeShow TimeShow =+    "…"+diffPrimitiveExpression l r@TimeShow =+    mismatch l r+diffPrimitiveExpression l@TimeShow r=+    mismatch l r+diffPrimitiveExpression TimeZone TimeZone =+    "…"+diffPrimitiveExpression l r@TimeZone =+    mismatch l r+diffPrimitiveExpression l@TimeZone r=+    mismatch l r+diffPrimitiveExpression TimeZoneShow TimeZoneShow =+    "…"+diffPrimitiveExpression l r@TimeZoneShow =+    mismatch l r+diffPrimitiveExpression l@TimeZoneShow r=+    mismatch l r diffPrimitiveExpression List List =     "…" diffPrimitiveExpression l@List r =@@ -1341,6 +1432,24 @@ diffPrimitiveExpression l@(TextLit {}) r =     mismatch l r diffPrimitiveExpression l r@(TextLit {}) =+    mismatch l r+diffPrimitiveExpression (DateLiteral l) (DateLiteral r) =+    diffDateLiteral l r+diffPrimitiveExpression l@(DateLiteral {}) r =+    mismatch l r+diffPrimitiveExpression l r@(DateLiteral {}) =+    mismatch l r+diffPrimitiveExpression (TimeLiteral tL pL) (TimeLiteral tR pR) =+    diffTimeLiteral tL pL tR pR+diffPrimitiveExpression l@(TimeLiteral {}) r =+    mismatch l r+diffPrimitiveExpression l r@(TimeLiteral {}) =+    mismatch l r+diffPrimitiveExpression (TimeZoneLiteral l) (TimeZoneLiteral r) =+    diffTimeZoneLiteral l r+diffPrimitiveExpression l@(TimeZoneLiteral {}) r =+    mismatch l r+diffPrimitiveExpression l r@(TimeZoneLiteral {}) =     mismatch l r diffPrimitiveExpression (Record aL) (Record aR) =     diffRecord aL aR
src/Dhall/DirectoryTree.hs view
@@ -1,31 +1,67 @@+{-# LANGUAGE CPP               #-} {-# LANGUAGE OverloadedLists   #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards   #-}+{-# LANGUAGE TupleSections     #-} {-# LANGUAGE ViewPatterns      #-} +{-# OPTIONS_GHC -Wno-orphans #-}+ -- | Implementation of the @dhall to-directory-tree@ subcommand module Dhall.DirectoryTree     ( -- * Filesystem       toDirectoryTree     , FilesystemError(..)++      -- * Low-level types and functions+    , module Dhall.DirectoryTree.Types+    , decodeDirectoryTree+    , directoryTreeType     ) where -import Control.Applicative (empty)-import Control.Exception   (Exception)-import Data.Void           (Void)-import Dhall.Syntax        (Chunks (..), Expr (..), RecordField (..))-import System.FilePath     ((</>))+import Control.Applicative       (empty)+import Control.Exception         (Exception)+import Control.Monad             (unless, when)+import Data.Either.Validation    (Validation (..))+import Data.Functor.Identity     (Identity (..))+import Data.Maybe                (fromMaybe, isJust)+import Data.Sequence             (Seq)+import Data.Text                 (Text)+import Data.Void                 (Void)+import Dhall.DirectoryTree.Types+import Dhall.Marshal.Decode      (Decoder (..), Expector)+import Dhall.Src                 (Src)+import Dhall.Syntax+    ( Chunks (..)+    , Const (..)+    , Expr (..)+    , RecordField (..)+    , Var (..)+    )+import System.FilePath           ((</>))+import System.PosixCompat.Types  (FileMode, GroupID, UserID) -import qualified Control.Exception                       as Exception-import qualified Data.Foldable                           as Foldable-import qualified Data.Text                               as Text-import qualified Data.Text.IO                            as Text.IO-import qualified Data.Text.Prettyprint.Doc.Render.String as Pretty-import qualified Dhall.Map                               as Map+import qualified Control.Exception           as Exception+import qualified Data.ByteString             as ByteString+import qualified Data.Foldable               as Foldable+import qualified Data.Text                   as Text+import qualified Data.Text.IO                as Text.IO+import qualified Dhall.Core                  as Core+import qualified Dhall.Map                   as Map+import qualified Dhall.Marshal.Decode        as Decode import qualified Dhall.Pretty-import qualified Dhall.Util                              as Util-import qualified System.Directory                        as Directory-import qualified System.FilePath                         as FilePath+import qualified Dhall.TypeCheck             as TypeCheck+import qualified Dhall.Util                  as Util+import qualified Prettyprinter               as Pretty+import qualified Prettyprinter.Render.String as Pretty+import qualified System.Directory            as Directory+import qualified System.FilePath             as FilePath+#ifdef mingw32_HOST_OS+import System.IO.Error           (illegalOperationErrorType, mkIOError)+#else+import qualified System.Posix.User           as Posix+#endif+import qualified System.PosixCompat.Files    as Posix  {-| Attempt to transform a Dhall record into a directory tree where: @@ -37,6 +73,9 @@      * @Optional@ values are omitted if @None@ +    * There is a more advanced way to construct directory trees using a fixpoint+      encoding. See the documentation below on that.+     For example, the following Dhall record:      > { dir = { `hello.txt` = "Hello\n" }@@ -59,8 +98,7 @@     > Goodbye      Use this in conjunction with the Prelude's support for rendering JSON/YAML-    in "pure Dhall" so that you can generate files containing JSON.  For-    example:+    in "pure Dhall" so that you can generate files containing JSON. For example:      > let JSON =     >       https://prelude.dhall-lang.org/v12.0.0/JSON/package.dhall sha256:843783d29e60b558c2de431ce1206ce34bdfde375fcf06de8ec5bf77092fdef7@@ -81,17 +119,69 @@     > ! "bar": null     > ! "foo": "Hello" -    This utility does not take care of type-checking and normalizing the-    provided expression.  This will raise a `FilesystemError` exception upon-    encountering an expression that cannot be converted as-is.+    /Advanced construction of directory trees/++    In addition to the ways described above using "simple" Dhall values to+    construct the directory tree there is one based on a fixpoint encoding. It+    works by passing a value of the following type to the interpreter:++    > let User = < UserId : Natural | UserName : Text >+    >+    > let Group = < GroupId : Natural | GroupName : Text >+    >+    > let Access =+    >       { execute : Optional Bool+    >       , read : Optional Bool+    >       , write : Optional Bool+    >       }+    >+    > let Mode =+    >       { user : Optional Access+    >       , group : Optional Access+    >       , other : Optional Access+    >       }+    >+    > let Entry =+    >       \(content : Type) ->+    >         { name : Text+    >         , content : content+    >         , user : Optional User+    >         , group : Optional Group+    >         , mode : Optional Mode+    >         }+    >+    > in  forall (tree : Type) ->+    >     forall  ( make+    >             : { directory : Entry (List tree) -> tree+    >               , file : Entry Text -> tree+    >               }+    >             ) ->+    >       List tree++    The fact that the metadata for filesystem entries is modeled after the POSIX+    permission model comes with the unfortunate downside that it might not apply+    to other systems: There, changes to the metadata (user, group, permissions)+    might be a no-op and __no warning will be issued__.+    This is a leaking abstraction of the+    [unix-compat](https://hackage.haskell.org/package/unix-compat) package used+    internally.++    __NOTE__: This utility does not take care of type-checking and normalizing+    the provided expression. This will raise a `FilesystemError` exception or a+    `Dhall.Marshal.Decode.DhallErrors` exception upon encountering an expression+    that cannot be converted as-is. -}-toDirectoryTree :: FilePath -> Expr Void Void -> IO ()-toDirectoryTree path expression = case expression of+toDirectoryTree+    :: Bool -- ^ Whether to allow path separators in file names or not+    -> FilePath+    -> Expr Void Void+    -> IO ()+toDirectoryTree allowSeparators path expression = case expression of     RecordLit keyValues ->         Map.unorderedTraverseWithKey_ process $ recordFieldValue <$> keyValues -    ListLit (Just (Record [ ("mapKey", recordFieldValue -> Text), ("mapValue", _) ])) [] ->-        return ()+    ListLit (Just (App List (Record [ ("mapKey", recordFieldValue -> Text), ("mapValue", _) ]))) [] ->+        Directory.createDirectoryIfMissing allowSeparators path      ListLit _ records         | not (null records)@@ -102,14 +192,22 @@         Text.IO.writeFile path text      Some value ->-        toDirectoryTree path value+        toDirectoryTree allowSeparators path value -    App (Field (Union _) _) value ->-        toDirectoryTree path value+    App (Field (Union _) _) value -> do+        toDirectoryTree allowSeparators path value      App None _ ->         return () +    -- If this pattern matches we assume the user wants to use the fixpoint+    -- approach, hence we typecheck it and output error messages like we would+    -- do for every other Dhall program.+    Lam _ _ (Lam _ _ _) -> do+        entries <- decodeDirectoryTree expression++        processFilesystemEntryList allowSeparators path entries+     _ ->         die   where@@ -124,18 +222,209 @@         empty      process key value = do-        if Text.isInfixOf (Text.pack [ FilePath.pathSeparator ]) key-            then die-            else return ()+        when (not allowSeparators && Text.isInfixOf (Text.pack [ FilePath.pathSeparator ]) key) $+            die -        Directory.createDirectoryIfMissing False path+        Directory.createDirectoryIfMissing allowSeparators path -        toDirectoryTree (path </> Text.unpack key) value+        toDirectoryTree allowSeparators (path </> Text.unpack key) value      die = Exception.throwIO FilesystemError{..}       where         unexpectedExpression = expression +-- | Decode a fixpoint directory tree from a Dhall expression.+decodeDirectoryTree :: Expr s Void -> IO (Seq FilesystemEntry)+decodeDirectoryTree (Core.alphaNormalize . Core.denote -> expression@(Lam _ _ (Lam _ _ body))) = do+    expected' <- case directoryTreeType of+        Success x -> return x+        Failure e -> Exception.throwIO e++    _ <- Core.throws $ TypeCheck.typeOf $ Annot expression expected'++    case Decode.extract decoder body of+        Success x -> return x+        Failure e -> Exception.throwIO e+    where+        decoder :: Decoder (Seq FilesystemEntry)+        decoder = Decode.auto+decodeDirectoryTree expr = Exception.throwIO $ FilesystemError $ Core.denote expr++-- | The type of a fixpoint directory tree expression.+directoryTreeType :: Expector (Expr Src Void)+directoryTreeType = Pi Nothing "tree" (Const Type)+    <$> (Pi Nothing "make" <$> makeType <*> pure (App List (Var (V "tree" 0))))++-- | The type of make part of a fixpoint directory tree expression.+makeType :: Expector (Expr Src Void)+makeType = Record . Map.fromList <$> sequenceA+    [ makeConstructor "directory" (Decode.auto :: Decoder DirectoryEntry)+    , makeConstructor "file" (Decode.auto :: Decoder TextFileEntry)+    , makeConstructor "binary-file" (Decode.auto :: Decoder BinaryFileEntry)+    ]+    where+        makeConstructor :: Text -> Decoder b -> Expector (Text, RecordField Src Void)+        makeConstructor name dec = (name,) . Core.makeRecordField+            <$> (Pi Nothing "_" <$> expected dec <*> pure (Var (V "tree" 0)))++-- | Resolve a `User` to a numerical id.+getUser :: User -> IO UserID+getUser (UserId uid) = return uid+getUser (UserName name) =+#ifdef mingw32_HOST_OS+    ioError $ mkIOError illegalOperationErrorType x Nothing Nothing+    where x = "System.Posix.User.getUserEntryForName: not supported"+#else+    Posix.userID <$> Posix.getUserEntryForName name+#endif++-- | Resolve a `Group` to a numerical id.+getGroup :: Group -> IO GroupID+getGroup (GroupId gid) = return gid+getGroup (GroupName name) =+#ifdef mingw32_HOST_OS+    ioError $ mkIOError illegalOperationErrorType x Nothing Nothing+    where x = "System.Posix.User.getGroupEntryForName: not supported"+#else+    Posix.groupID <$> Posix.getGroupEntryForName name+#endif++-- | Process a `FilesystemEntry`. Writes the content to disk and apply the+-- metadata to the newly created item.+processFilesystemEntry :: Bool -> FilePath -> FilesystemEntry -> IO ()+processFilesystemEntry allowSeparators path (DirectoryEntry entry) =+    processEntryWith path entry $ \path' content -> do+        Directory.createDirectoryIfMissing allowSeparators path'+        processFilesystemEntryList allowSeparators path' content+processFilesystemEntry allowSeparators path (BinaryFileEntry entry) =+    processEntryWith path entry $ \path' content -> do+        when allowSeparators $ do+            Directory.createDirectoryIfMissing True (FilePath.takeDirectory path')+        ByteString.writeFile path' content+processFilesystemEntry allowSeparators path (TextFileEntry entry) =+    processEntryWith path entry $ \path' content -> do+        when allowSeparators $ do+            Directory.createDirectoryIfMissing True (FilePath.takeDirectory path')+        Text.IO.writeFile path' content++-- | A helper function used by 'processFilesystemEntry'.+processEntryWith+    :: FilePath+    -> Entry a+    -> (FilePath -> a -> IO ())+    -> IO ()+processEntryWith path entry f = do+    let path' = path </> entryName entry+    when (hasMetadata entry && not isMetadataSupported) $+        Exception.throwIO (MetadataUnsupportedError path')+    f path' (entryContent entry)+    -- It is important that we write the metadata after we wrote the content of+    -- the file as we might lock ourself out by changing ownership or+    -- permissions.+    applyMetadata entry path'++-- | Process a list of `FilesystemEntry`s.+processFilesystemEntryList :: Bool -> FilePath -> Seq FilesystemEntry -> IO ()+processFilesystemEntryList allowSeparators path = Foldable.traverse_+    (processFilesystemEntry allowSeparators path)++-- | Does this entry have some metadata set?+hasMetadata :: Entry a -> Bool+hasMetadata entry+    =  isJust (entryUser entry)+    || isJust (entryGroup entry)+    || maybe False hasMode (entryMode entry)+    where+        hasMode :: Mode Maybe -> Bool+        hasMode mode+            =  maybe False hasAccess (modeUser mode)+            || maybe False hasAccess (modeGroup mode)+            || maybe False hasAccess (modeOther mode)++        hasAccess :: Access Maybe -> Bool+        hasAccess access+            =  isJust (accessExecute access)+            || isJust (accessRead access)+            || isJust (accessWrite access)++-- | Set the metadata of an object referenced by a path.+applyMetadata :: Entry a -> FilePath -> IO ()+applyMetadata entry fp = do+    s <- Posix.getFileStatus fp+    let user = Posix.fileOwner s+        group = Posix.fileGroup s+        mode = fileModeToMode $ Posix.fileMode s++    user' <- getUser $ fromMaybe (UserId user) (entryUser entry)+    group' <- getGroup $ fromMaybe (GroupId group) (entryGroup entry)+    unless ((user', group') == (user, group)) $+        Posix.setOwnerAndGroup fp user' group'++    let mode' = maybe mode (updateModeWith mode) (entryMode entry)+    unless (mode' == mode) $+        setFileMode fp $ modeToFileMode mode'++-- | Calculate the new `Mode` from the current mode and the changes specified by+-- the user.+updateModeWith :: Mode Identity -> Mode Maybe -> Mode Identity+updateModeWith x y = Mode+    { modeUser = combine modeUser modeUser+    , modeGroup = combine modeGroup modeGroup+    , modeOther = combine modeOther modeOther+    }+    where+        combine f g = maybe (f x) (Identity . updateAccessWith (runIdentity $ f x)) (g y)++-- | Calculate the new `Access` from the current permissions and the changes+-- specified by the user.+updateAccessWith :: Access Identity -> Access Maybe -> Access Identity+updateAccessWith x y = Access+    { accessExecute = combine accessExecute accessExecute+    , accessRead = combine accessRead accessRead+    , accessWrite = combine accessWrite accessWrite+    }+    where+        combine f g = maybe (f x) Identity (g y)++-- | Convert a filesystem mode given as a bitmask (`FileMode`) to an ADT+-- (`Mode`).+fileModeToMode :: FileMode -> Mode Identity+fileModeToMode mode = Mode+    { modeUser = Identity $ Access+        { accessExecute = Identity $ mode `hasFileMode` Posix.ownerExecuteMode+        , accessRead = Identity $ mode `hasFileMode` Posix.ownerReadMode+        , accessWrite = Identity $ mode `hasFileMode` Posix.ownerReadMode+        }+    , modeGroup = Identity $ Access+        { accessExecute = Identity $ mode `hasFileMode` Posix.groupExecuteMode+        , accessRead = Identity $ mode `hasFileMode` Posix.groupReadMode+        , accessWrite = Identity $ mode `hasFileMode` Posix.groupReadMode+        }+    , modeOther = Identity $ Access+        { accessExecute = Identity $ mode `hasFileMode` Posix.otherExecuteMode+        , accessRead = Identity $ mode `hasFileMode` Posix.otherReadMode+        , accessWrite = Identity $ mode `hasFileMode` Posix.otherReadMode+        }+    }++-- | Convert a filesystem mode given as an ADT (`Mode`) to a bitmask+-- (`FileMode`).+modeToFileMode :: Mode Identity -> FileMode+modeToFileMode mode = foldr Posix.unionFileModes Posix.nullFileMode $+    [ Posix.ownerExecuteMode | runIdentity $ accessExecute (runIdentity $ modeUser  mode) ] <>+    [ Posix.ownerReadMode    | runIdentity $ accessRead    (runIdentity $ modeUser  mode) ] <>+    [ Posix.ownerWriteMode   | runIdentity $ accessWrite   (runIdentity $ modeUser  mode) ] <>+    [ Posix.groupExecuteMode | runIdentity $ accessExecute (runIdentity $ modeGroup mode) ] <>+    [ Posix.groupReadMode    | runIdentity $ accessRead    (runIdentity $ modeGroup mode) ] <>+    [ Posix.groupWriteMode   | runIdentity $ accessWrite   (runIdentity $ modeGroup mode) ] <>+    [ Posix.otherExecuteMode | runIdentity $ accessExecute (runIdentity $ modeOther mode) ] <>+    [ Posix.otherReadMode    | runIdentity $ accessRead    (runIdentity $ modeOther mode) ] <>+    [ Posix.otherWriteMode   | runIdentity $ accessWrite   (runIdentity $ modeOther mode) ]++-- | Check whether the second `FileMode` is contained in the first one.+hasFileMode :: FileMode -> FileMode -> Bool+hasFileMode mode x = (mode `Posix.intersectFileModes` x) == x+ {- | This error indicates that you supplied an invalid Dhall expression to the      `toDirectoryTree` function.  The Dhall expression could not be translated      to a directory tree.@@ -143,59 +432,84 @@ newtype FilesystemError =     FilesystemError { unexpectedExpression :: Expr Void Void } +instance Exception FilesystemError+ instance Show FilesystemError where     show FilesystemError{..} =         Pretty.renderString (Dhall.Pretty.layout message)       where         message =-          Util._ERROR <> ": Not a valid directory tree expression                             \n\-          \                                                                                   \n\-          \Explanation: Only a subset of Dhall expressions can be converted to a directory    \n\-          \tree.  Specifically, record literals or maps can be converted to directories,      \n\-          \❰Text❱ literals can be converted to files, and ❰Optional❱ values are included if   \n\-          \❰Some❱ and omitted if ❰None❱.  Values of union types can also be converted if      \n\-          \they are an alternative which has a non-nullary constructor whose argument is of   \n\-          \an otherwise convertible type.  No other type of value can be translated to a      \n\-          \directory tree.                                                                    \n\-          \                                                                                   \n\-          \For example, this is a valid expression that can be translated to a directory      \n\-          \tree:                                                                              \n\-          \                                                                                   \n\-          \                                                                                   \n\-          \    ┌──────────────────────────────────┐                                           \n\-          \    │ { `example.json` = \"[1, true]\" } │                                         \n\-          \    └──────────────────────────────────┘                                           \n\-          \                                                                                   \n\-          \                                                                                   \n\-          \In contrast, the following expression is not allowed due to containing a           \n\-          \❰Natural❱ field, which cannot be translated in this way:                           \n\-          \                                                                                   \n\-          \                                                                                   \n\-          \    ┌───────────────────────┐                                                      \n\-          \    │ { `example.txt` = 1 } │                                                      \n\-          \    └───────────────────────┘                                                      \n\-          \                                                                                   \n\-          \                                                                                   \n\-          \Note that key names cannot contain path separators:                                \n\-          \                                                                                   \n\-          \                                                                                   \n\-          \    ┌─────────────────────────────────────┐                                        \n\-          \    │ { `directory/example.txt` = \"ABC\" } │ Invalid: Key contains a forward slash\n\-          \    └─────────────────────────────────────┘                                        \n\-          \                                                                                   \n\-          \                                                                                   \n\-          \Instead, you need to refactor the expression to use nested records instead:        \n\-          \                                                                                   \n\-          \                                                                                   \n\-          \    ┌───────────────────────────────────────────┐                                  \n\-          \    │ { directory = { `example.txt` = \"ABC\" } } │                                \n\-          \    └───────────────────────────────────────────┘                                  \n\-          \                                                                                   \n\-          \                                                                                   \n\-          \You tried to translate the following expression to a directory tree:               \n\-          \                                                                                   \n\-          \" <> Util.insert unexpectedExpression <> "\n\-          \                                                                                   \n\+          Util._ERROR <> ": Not a valid directory tree expression                             \n\\+          \                                                                                   \n\\+          \Explanation: Only a subset of Dhall expressions can be converted to a directory    \n\\+          \tree.  Specifically, record literals or maps can be converted to directories,      \n\\+          \❰Text❱ literals can be converted to files, and ❰Optional❱ values are included if   \n\\+          \❰Some❱ and omitted if ❰None❱.  Values of union types can also be converted if      \n\\+          \they are an alternative which has a non-nullary constructor whose argument is of   \n\\+          \an otherwise convertible type.  Furthermore, there is a more advanced approach to  \n\\+          \constructing a directory tree utilizing a fixpoint encoding. Consult the upstream  \n\\+          \documentation of the `toDirectoryTree` function in the Dhall.Directory module for  \n\\+          \further information on that.                                                       \n\\+          \No other type of value can be translated to a directory tree.                      \n\\+          \                                                                                   \n\\+          \For example, this is a valid expression that can be translated to a directory      \n\\+          \tree:                                                                              \n\\+          \                                                                                   \n\\+          \                                                                                   \n\\+          \    ┌──────────────────────────────────┐                                           \n\\+          \    │ { `example.json` = \"[1, true]\" } │                                         \n\\+          \    └──────────────────────────────────┘                                           \n\\+          \                                                                                   \n\\+          \                                                                                   \n\\+          \In contrast, the following expression is not allowed due to containing a           \n\\+          \❰Natural❱ field, which cannot be translated in this way:                           \n\\+          \                                                                                   \n\\+          \                                                                                   \n\\+          \    ┌───────────────────────┐                                                      \n\\+          \    │ { `example.txt` = 1 } │                                                      \n\\+          \    └───────────────────────┘                                                      \n\\+          \                                                                                   \n\\+          \                                                                                   \n\\+          \Note that key names cannot contain path separators:                                \n\\+          \                                                                                   \n\\+          \                                                                                   \n\\+          \    ┌─────────────────────────────────────┐                                        \n\\+          \    │ { `directory/example.txt` = \"ABC\" } │ Invalid: Key contains a forward slash\n\\+          \    └─────────────────────────────────────┘                                        \n\\+          \                                                                                   \n\\+          \                                                                                   \n\\+          \Instead, you need to refactor the expression to use nested records instead:        \n\\+          \                                                                                   \n\\+          \                                                                                   \n\\+          \    ┌───────────────────────────────────────────┐                                  \n\\+          \    │ { directory = { `example.txt` = \"ABC\" } } │                                \n\\+          \    └───────────────────────────────────────────┘                                  \n\\+          \                                                                                   \n\\+          \                                                                                   \n\\+          \You tried to translate the following expression to a directory tree:               \n\\+          \                                                                                   \n\\+          \" <> Util.insert unexpectedExpression <> "\n\\+          \                                                                                   \n\\           \... which is not an expression that can be translated to a directory tree.         \n" -instance Exception FilesystemError+{- | This error indicates that you want to set some metadata for a file or+     directory, but that operation is not supported  on your platform.+-}+newtype MetadataUnsupportedError =+    MetadataUnsupportedError { metadataForPath :: FilePath }++instance Exception MetadataUnsupportedError++instance Show MetadataUnsupportedError where+    show MetadataUnsupportedError{..} =+        Pretty.renderString (Dhall.Pretty.layout message)+      where+        message =+          Util._ERROR <> ": Setting metadata is not supported on this platform.               \n\\+          \                                                                                   \n\\+          \Explanation: Your Dhall expression indicates that you intend to set some metadata  \n\\+          \like ownership or permissions for the following file or directory:                 \n\\+          \                                                                                   \n\\+          \" <> Pretty.pretty metadataForPath <> "\n\\+          \                                                                                   \n\\+          \... which is not supported on your platform.                                       \n"
+ src/Dhall/DirectoryTree/Types.hs view
@@ -0,0 +1,267 @@+{-# LANGUAGE CPP                #-}+{-# LANGUAGE DeriveGeneric      #-}+{-# LANGUAGE FlexibleInstances  #-}+{-# LANGUAGE LambdaCase         #-}+{-# LANGUAGE OverloadedStrings  #-}+{-# LANGUAGE PatternSynonyms    #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeApplications   #-}+{-# LANGUAGE ViewPatterns       #-}++{-# OPTIONS_GHC -Wno-orphans #-}++-- | Types used by the implementation of the @to-directory-tree@ subcommand+module Dhall.DirectoryTree.Types+    ( FilesystemEntry(DirectoryEntry, BinaryFileEntry, TextFileEntry, FileEntry)+    , DirectoryEntry+    , FileEntry+    , BinaryFileEntry+    , TextFileEntry+    , Entry(..)+    , User(..)+    , Group(..)+    , Mode(..)+    , Access(..)++    , setFileMode+    , prettyFileMode++    , isMetadataSupported+    ) where++import Data.ByteString          (ByteString)+import Data.Functor.Identity    (Identity (..))+import Data.Sequence            (Seq)+import Data.Text                (Text)+import Dhall.Marshal.Decode+    ( Decoder (..)+    , FromDhall (..)+    , Generic+    , InputNormalizer+    , InterpretOptions (..)+    )+import Dhall.Syntax             (Expr (..), FieldSelection (..), Var (..))+import System.PosixCompat.Types (GroupID, UserID)++import qualified Data.Text                as Text+import qualified Dhall.Marshal.Decode     as Decode+import qualified System.PosixCompat.Files as Posix++#ifdef mingw32_HOST_OS+import Control.Monad            (unless)+import Data.Word                (Word32)+import System.IO                (hPutStrLn, stderr)+import System.PosixCompat.Types (CMode)++import qualified Unsafe.Coerce++type FileMode = CMode+#else+import System.PosixCompat.Types (FileMode)++import qualified System.PosixCompat.Types as Posix+#endif++pattern Make :: Text -> Expr s a -> Expr s a+pattern Make label entry <- App (Field (Var (V "_" 0)) (fieldSelectionLabel -> label)) entry++-- | A directory in the filesystem.+type DirectoryEntry = Entry (Seq FilesystemEntry)++-- | A file in the filesystem.+{-# DEPRECATED FileEntry "`FileEntry` is deprecated and will be removed eventually. Please use `TextFileEntry` instead." #-}+type FileEntry = Entry Text++-- | A binary file in the filesystem.+type BinaryFileEntry = Entry ByteString++-- | A text file in the filesystem.+type TextFileEntry = Entry Text++-- | A filesystem entry.+data FilesystemEntry+    = DirectoryEntry (Entry (Seq FilesystemEntry))+    | BinaryFileEntry BinaryFileEntry+    | TextFileEntry TextFileEntry+    deriving (Eq, Generic, Ord, Show)++pattern FileEntry :: Entry Text -> FilesystemEntry+pattern FileEntry entry = TextFileEntry entry++instance FromDhall FilesystemEntry where+    autoWith normalizer = Decoder+        { expected = pure $ Var (V "tree" 0)+        , extract = \case+            Make "directory" entry ->+                DirectoryEntry <$> extract (autoWith normalizer) entry+            Make "file" entry ->+                TextFileEntry <$> extract (autoWith normalizer) entry+            Make "binary-file" entry ->+                BinaryFileEntry <$> extract (autoWith normalizer) entry+            expr -> Decode.typeError (expected (Decode.autoWith normalizer :: Decoder FilesystemEntry)) expr+        }++-- | A generic filesystem entry. This type holds the metadata that apply to all+-- entries. It is parametric over the content of such an entry.+data Entry a = Entry+    { entryName :: String+    , entryContent :: a+    , entryUser :: Maybe User+    , entryGroup :: Maybe Group+    , entryMode :: Maybe (Mode Maybe)+    }+    deriving (Eq, Generic, Ord, Show)++instance FromDhall a => FromDhall (Entry a) where+    autoWith = Decode.genericAutoWithInputNormalizer Decode.defaultInterpretOptions+        { fieldModifier = Text.toLower . Text.drop (Text.length "entry")+        }++-- | A user identified either by id or name.+data User+    = UserId UserID+    | UserName String+    deriving (Eq, Generic, Ord, Show)++instance FromDhall User++#ifdef mingw32_HOST_OS+instance FromDhall UserID where+    autoWith normalizer = Unsafe.Coerce.unsafeCoerce <$> autoWith @Word32 normalizer+#else+instance FromDhall Posix.CUid where+    autoWith normalizer = Posix.CUid <$> autoWith normalizer+#endif++-- | A group identified either by id or name.+data Group+    = GroupId GroupID+    | GroupName String+    deriving (Eq, Generic, Ord, Show)++instance FromDhall Group++#ifdef mingw32_HOST_OS+instance FromDhall GroupID where+    autoWith normalizer = Unsafe.Coerce.unsafeCoerce <$> autoWith @Word32 normalizer+#else+instance FromDhall Posix.CGid where+    autoWith normalizer = Posix.CGid <$> autoWith normalizer+#endif++-- | A filesystem mode. See chmod(1).+-- The parameter is meant to be instantiated by either `Identity` or `Maybe`+-- depending on the completeness of the information:+--  * For data read from the filesystem it will be `Identity`.+--  * For user-supplied data it will be `Maybe` as we want to be able to set+--    only specific bits.+data Mode f = Mode+    { modeUser :: f (Access f)+    , modeGroup :: f (Access f)+    , modeOther :: f (Access f)+    }+    deriving Generic++deriving instance Eq (Mode Identity)+deriving instance Eq (Mode Maybe)+deriving instance Ord (Mode Identity)+deriving instance Ord (Mode Maybe)+deriving instance Show (Mode Identity)+deriving instance Show (Mode Maybe)++instance FromDhall (Mode Identity) where+    autoWith = modeDecoder++instance FromDhall (Mode Maybe) where+    autoWith = modeDecoder++modeDecoder :: FromDhall (f (Access f)) => InputNormalizer -> Decoder (Mode f)+modeDecoder = Decode.genericAutoWithInputNormalizer Decode.defaultInterpretOptions+    { fieldModifier = Text.toLower . Text.drop (Text.length "mode")+    }++-- | The permissions for a subject (user/group/other).+data Access f = Access+    { accessExecute :: f Bool+    , accessRead :: f Bool+    , accessWrite :: f Bool+    }+    deriving Generic++deriving instance Eq (Access Identity)+deriving instance Eq (Access Maybe)+deriving instance Ord (Access Identity)+deriving instance Ord (Access Maybe)+deriving instance Show (Access Identity)+deriving instance Show (Access Maybe)++instance FromDhall (Access Identity) where+    autoWith = accessDecoder++instance FromDhall (Access Maybe) where+    autoWith = accessDecoder++accessDecoder :: FromDhall (f Bool) => InputNormalizer -> Decoder (Access f)+accessDecoder = Decode.genericAutoWithInputNormalizer Decode.defaultInterpretOptions+    { fieldModifier = Text.toLower . Text.drop (Text.length "access")+    }++++-- | A wrapper around `Posix.setFileMode`. On Windows, it does check the+-- resulting file mode of the file/directory and emits a warning if it doesn't+-- match the desired file mode. On all other OS it is identical to+-- `Posix.setFileMode` as it is assumed to work correctly.+setFileMode :: FilePath -> FileMode -> IO ()+#ifdef mingw32_HOST_OS+setFileMode fp mode = do+    Posix.setFileMode fp mode+    mode' <- Posix.fileMode <$> Posix.getFileStatus fp+    unless (mode' == mode) $ hPutStrLn stderr $+        "Warning: Setting file mode did not succeed for " <> fp <> "\n" <>+        "    Expected: " <> prettyFileMode mode <> "\n" <>+        "    Actual:   " <> prettyFileMode mode'+#else+setFileMode fp mode = Posix.setFileMode fp mode+#endif++-- | Pretty-print a `FileMode`. The format is similar to the one ls(1):+-- It is display as three blocks of three characters. The first block are the+-- permissions of the user, the second one are the ones of the group and the+-- third one the ones of other subjects. A @r@ denotes that the file or+-- directory is readable by the subject, a @w@ denotes that it is writable and+-- an @x@ denotes that it is executable. Unset permissions are represented by+-- @-@.+prettyFileMode :: FileMode -> String+prettyFileMode mode = userPP <> groupPP <> otherPP+    where+        userPP :: String+        userPP =+            isBitSet 'r' Posix.ownerReadMode <>+            isBitSet 'w' Posix.ownerWriteMode <>+            isBitSet 'x' Posix.ownerExecuteMode++        groupPP :: String+        groupPP =+            isBitSet 'r' Posix.groupReadMode <>+            isBitSet 'w' Posix.groupWriteMode <>+            isBitSet 'x' Posix.groupExecuteMode++        otherPP :: String+        otherPP =+            isBitSet 'r' Posix.otherReadMode <>+            isBitSet 'w' Posix.otherWriteMode <>+            isBitSet 'x' Posix.otherExecuteMode++        isBitSet :: Char -> FileMode -> String+        isBitSet c mask = if mask `Posix.intersectFileModes` mode /= Posix.nullFileMode+            then [c]+            else "-"++-- | Is setting metadata supported on this platform or not.+isMetadataSupported :: Bool+#ifdef mingw32_HOST_OS+isMetadataSupported = False+#else+isMetadataSupported = True+#endif
src/Dhall/Eval.hs view
@@ -10,8 +10,6 @@ {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE ViewPatterns         #-} -{-# OPTIONS_GHC -O #-}- {-| Eval-apply environment machine with conversion checking and quoting to     normal forms. Fairly similar to GHCI's STG machine algorithmically, but much     simpler, with no known call optimization or environment trimming.@@ -48,12 +46,18 @@   , Val(..)   , (~>)   , textShow+  , dateShow+  , timeShow+  , timezoneShow   ) where +import Data.Bifunctor     (first)+import Data.ByteString    (ByteString) import Data.Foldable      (foldr', toList)-import Data.List.NonEmpty (NonEmpty(..))+import Data.List.NonEmpty (NonEmpty (..)) import Data.Sequence      (Seq, ViewL (..), ViewR (..)) import Data.Text          (Text)+import Data.Time          (Day, TimeOfDay (..), TimeZone) import Data.Void          (Void) import Dhall.Map          (Map) import Dhall.Set          (Set)@@ -70,16 +74,18 @@     , PreferAnnotation (..)     , RecordField (..)     , Var (..)+    , WithComponent (..)     )  import qualified Data.Char import qualified Data.Sequence as Sequence import qualified Data.Set import qualified Data.Text     as Text+import qualified Data.Time     as Time import qualified Dhall.Map     as Map import qualified Dhall.Set import qualified Dhall.Syntax  as Syntax-import qualified Text.Printf+import qualified Text.Printf   as Printf  data Environment a     = Empty@@ -133,6 +139,10 @@   -- ^ The original function was a @Natural/subtract 0@.  We need to preserve   --   this information in case the @Natural/subtract@ ends up not being fully   --   saturated, in which case we need to recover the unsaturated built-in+  | TextReplaceEmpty+  -- ^ The original function was a @Text/replace ""@+  | TextReplaceEmptyArgument (Val a)+  -- ^ The original function was a @Text/replace "" replacement@  deriving instance (Show a, Show (Val a -> Val a)) => Show (HLamInfo a) @@ -143,6 +153,7 @@ toVHPi (VPi a b@(Closure x _ _)) = Just (x, a, instantiate b) toVHPi (VHPi x a b             ) = Just (x, a, b) toVHPi  _                        = Nothing+{-# INLINABLE toVHPi #-}  data Val a     = VConst !Const@@ -164,6 +175,9 @@     | VBoolNE !(Val a) !(Val a)     | VBoolIf !(Val a) !(Val a) !(Val a) +    | VBytes+    | VBytesLit ByteString+     | VNatural     | VNaturalLit !Natural     | VNaturalFold !(Val a) !(Val a) !(Val a) !(Val a)@@ -194,6 +208,16 @@     | VTextShow !(Val a)     | VTextReplace !(Val a) !(Val a) !(Val a) +    | VDate+    | VDateLiteral Time.Day+    | VDateShow !(Val a)+    | VTime+    | VTimeLiteral Time.TimeOfDay Word+    | VTimeShow !(Val a)+    | VTimeZone+    | VTimeZoneLiteral Time.TimeZone+    | VTimeZoneShow !(Val a)+     | VList !(Val a)     | VListLit !(Maybe (Val a)) !(Seq (Val a))     | VListAppend !(Val a) !(Val a)@@ -216,12 +240,13 @@     | VPrefer !(Val a) !(Val a)     | VMerge !(Val a) !(Val a) !(Maybe (Val a))     | VToMap !(Val a) !(Maybe (Val a))+    | VShowConstructor !(Val a)     | VField !(Val a) !Text     | VInject !(Map Text (Maybe (Val a))) !Text !(Maybe (Val a))     | VProject !(Val a) !(Either (Set Text) (Val a))     | VAssert !(Val a)     | VEquivalent !(Val a) !(Val a)-    | VWith !(Val a) (NonEmpty Text) !(Val a)+    | VWith !(Val a) (NonEmpty WithComponent) !(Val a)     | VEmbed a  -- | For use with "Text.Show.Functions".@@ -363,16 +388,15 @@     singletonVRecordLit v = VRecordLit (Map.singleton k v) {-# INLINE vField #-} -vTextReplaceSlow :: Text -> Val a -> VChunks a -> VChunks a-vTextReplaceSlow needle replacement haystack = go haystack+vTextReplace :: Text -> Val a -> Text -> VChunks a+vTextReplace needle replacement haystack = go haystack   where-    go (VChunks [] lastText) =-        if Text.null suffix-        then VChunks [] lastText-        else+    go t+        | Text.null suffix = VChunks [] t+        | otherwise =             let remainder = Text.drop (Text.length needle) suffix -                rest = go (VChunks [] remainder)+                rest = go remainder              in  case replacement of                     VTextLit replacementChunks ->@@ -380,36 +404,7 @@                     _ ->                         VChunks [(prefix, replacement)] "" <> rest       where-        (prefix, suffix) = Text.breakOn needle lastText-    go (VChunks ((firstText, firstInterpolation) : chunks) lastText) =-       if Text.null suffix-       then-           let rest = go (VChunks chunks lastText)--           in  VChunks [(firstText, firstInterpolation)] "" <> rest-       else-           let remainder = Text.drop (Text.length needle) suffix--               rest =-                   go (VChunks ((remainder, firstInterpolation) : chunks) lastText)--           in  case replacement of-                   VTextLit replacementChunks ->-                       VChunks [] prefix <> replacementChunks <> rest-                   _ ->-                       VChunks [(prefix, replacement)] "" <> rest-      where-        (prefix, suffix) = Text.breakOn needle firstText--vTextReplaceFast :: Text -> Text -> VChunks a -> VChunks a-vTextReplaceFast needle replacement (VChunks xys z) = VChunks xys' z'-  where-    xys' = do-       (x, y) <- xys--       return (Text.replace needle replacement x, y)--    z' = Text.replace needle replacement z+        (prefix, suffix) = Text.breakOn needle t  vProjectByFields :: Eq a => Environment a -> Val a -> Set Text -> Val a vProjectByFields env t ks =@@ -434,9 +429,9 @@             t' ->                 VProject t' (Left ks) -vWith :: Val a -> NonEmpty Text -> Val a -> Val a-vWith (VRecordLit kvs) (k  :| []     ) v = VRecordLit (Map.insert k  v  kvs)-vWith (VRecordLit kvs) (k₀ :| k₁ : ks) v = VRecordLit (Map.insert k₀ e₂ kvs)+vWith :: Val a -> NonEmpty WithComponent -> Val a -> Val a+vWith (VRecordLit kvs) (WithLabel k  :| []     ) v = VRecordLit (Map.insert k  v  kvs)+vWith (VRecordLit kvs) (WithLabel k₀ :| k₁ : ks) v = VRecordLit (Map.insert k₀ e₂ kvs)   where     e₁ =         case Map.lookup k₀ kvs of@@ -444,6 +439,9 @@             Just e₁' -> e₁'      e₂ = vWith e₁ (k₁ :| ks) v+vWith (VNone _T) (WithQuestion :| _      ) _ = VNone _T+vWith (VSome  _) (WithQuestion :| []     ) v = VSome v+vWith (VSome  t) (WithQuestion :| k₁ : ks) v = VSome (vWith t (k₁ :| ks) v) vWith e₀ ks v₀ = VWith e₀ ks v₀  eval :: forall a. Eq a => Environment a -> Expr Void a -> Val a@@ -453,9 +451,9 @@             VConst k         Var v ->             vVar env v-        Lam (FunctionBinding { functionBindingVariable = x, functionBindingAnnotation = a }) t ->+        Lam _ (FunctionBinding { functionBindingVariable = x, functionBindingAnnotation = a }) t ->             VLam (eval env a) (Closure x env t)-        Pi x a b ->+        Pi _ x a b ->             VPi (eval env a) (Closure x env b)         App t u ->             vApp (eval env t) (eval env u)@@ -503,6 +501,10 @@                 (b', VBoolLit True, VBoolLit False) -> b'                 (_, t', f') | conv env t' f'        -> t'                 (b', t', f')                        -> VBoolIf b' t' f'+        Bytes ->+            VBytes+        BytesLit b ->+            VBytesLit b         Natural ->             VNatural         NaturalLit n ->@@ -525,9 +527,12 @@                                 -- following issue:                                 --                                 -- https://github.com/ghcjs/ghcjs/issues/782-                                let go !acc 0 = acc-                                    go  acc m = go (vApp succ acc) (m - 1)-                                in  go zero (fromIntegral n' :: Integer)+                                go zero (fromIntegral n' :: Integer) where+                                  go !acc 0 = acc+                                  go acc m =+                                  -- Detect a shortcut: if succ acc == acc then return acc immediately.+                                    let next = vApp succ acc+                                    in  if conv env next acc then acc else go next (m - 1)                             _ -> inert         NaturalBuild ->             VPrim $ \case@@ -631,33 +636,67 @@                 t                       -> VTextShow t         TextReplace ->             VPrim $ \needle ->-            VPrim $ \replacement ->-            VPrim $ \haystack ->-                case haystack of-                    VTextLit haystackChunks ->-                        case needle of-                            VTextLit (VChunks [] "") ->-                                haystack-                            VTextLit (VChunks [] needleText) ->-                                case replacement of-                                    VTextLit (VChunks [] replacementText) ->-                                        VTextLit-                                            (vTextReplaceFast-                                                needleText-                                                replacementText-                                                haystackChunks-                                            )-                                    _ ->-                                        VTextLit-                                            (vTextReplaceSlow-                                                needleText-                                                replacement-                                                haystackChunks-                                            )-                            _ ->-                                VTextReplace needle replacement haystack+            let hLamInfo0 = case needle of+                    VTextLit (VChunks [] "") -> TextReplaceEmpty+                    _                        -> Prim++            in  VHLam hLamInfo0 $ \replacement ->+            let hLamInfo1 = case needle of+                    VTextLit (VChunks [] "") ->+                        TextReplaceEmptyArgument replacement                     _ ->-                        VTextReplace needle replacement haystack+                        Prim+            in  VHLam hLamInfo1 $ \haystack ->+                    case needle of+                        VTextLit (VChunks [] "") ->+                            haystack++                        VTextLit (VChunks [] needleText) ->+                            case haystack of+                                VTextLit (VChunks [] haystackText) ->+                                    case replacement of+                                        VTextLit (VChunks [] replacementText) ->+                                            VTextLit $ VChunks []+                                                (Text.replace+                                                    needleText+                                                    replacementText+                                                    haystackText+                                                )+                                        _ ->+                                            VTextLit+                                                (vTextReplace+                                                    needleText+                                                    replacement+                                                    haystackText+                                                )+                                _ ->+                                    VTextReplace needle replacement haystack+                        _ ->+                            VTextReplace needle replacement haystack+        Date ->+            VDate+        DateLiteral d ->+            VDateLiteral d+        DateShow ->+            VPrim $ \case+                VDateLiteral d -> VTextLit (VChunks [] (dateShow d))+                t              -> VDateShow t+        Time ->+            VTime+        TimeLiteral t p ->+            VTimeLiteral t p+        TimeShow ->+            VPrim $ \case+                VTimeLiteral d p -> VTextLit (VChunks [] (timeShow d p))+                t                -> VTimeShow t+        TimeZone ->+            VTimeZone+        TimeZoneLiteral z ->+            VTimeZoneLiteral z+        TimeZoneShow ->+            VPrim $ \case+                VTimeZoneLiteral d -> VTextLit (VChunks [] (timezoneShow d))+                t                  -> VTimeZoneShow t         List ->             VPrim VList         ListLit ma ts ->@@ -762,14 +801,14 @@             VRecordLit (Map.sort (eval env . recordFieldValue <$> kts))         Union kts ->             VUnion (Map.sort (fmap (fmap (eval env)) kts))-        Combine mk t u ->+        Combine _ mk t u ->             vCombine mk (eval env t) (eval env u)-        CombineTypes t u ->+        CombineTypes _ t u ->             vCombineTypes (eval env t) (eval env u)-        Prefer _ t u ->+        Prefer _ _ t u ->             vPrefer env (eval env t) (eval env u)         RecordCompletion t u ->-            eval env (Annot (Prefer PreferFromCompletion (Field t def) u) (Field t typ))+            eval env (Annot (Prefer mempty PreferFromCompletion (Field t def) u) (Field t typ))           where             def = Syntax.makeFieldSelection "default"             typ = Syntax.makeFieldSelection "Type"@@ -803,19 +842,27 @@                     in  VListLit Nothing s                 (x', ma') ->                     VToMap x' ma'+        ShowConstructor x ->+            case eval env x of+                VInject m k _+                    | Just _ <- Map.lookup k m -> VTextLit (VChunks [] k)+                    | otherwise                -> error errorMsg+                VSome _ -> VTextLit (VChunks [] "Some")+                VNone _ -> VTextLit (VChunks [] "None")+                x' -> VShowConstructor x'         Field t (Syntax.fieldSelectionLabel -> k) ->             vField (eval env t) k         Project t (Left ks) ->-            vProjectByFields env (eval env t) (Dhall.Set.sort ks)+            vProjectByFields env (eval env t) (Dhall.Set.sort (Dhall.Set.fromList ks))         Project t (Right e) ->             case eval env e of                 VRecord kts ->-                    eval env (Project t (Left (Dhall.Set.fromSet (Map.keysSet kts))))+                    vProjectByFields env (eval env t) (Dhall.Set.fromSet (Map.keysSet kts))                 e' ->                     VProject (eval env t) (Right e')         Assert t ->             VAssert (eval env t)-        Equivalent t u ->+        Equivalent _ t u ->             VEquivalent (eval env t) (eval env u)         With e₀ ks v ->             vWith (eval env e₀) ks (eval env v)@@ -873,9 +920,32 @@     f '\r' = "\\r"     f '\t' = "\\t"     f '\f' = "\\f"-    f c | c <= '\x1F' = Text.pack (Text.Printf.printf "\\u%04x" (Data.Char.ord c))+    f c | c <= '\x1F' = Text.pack (Printf.printf "\\u%04x" (Data.Char.ord c))         | otherwise   = Text.singleton c +-- | Utility that powers the @Date/show@ built-in+dateShow :: Day -> Text+dateShow = Text.pack . Time.formatTime Time.defaultTimeLocale "%0Y-%m-%d"++-- | Utility that powers the @Time/show@ built-in+timeShow :: TimeOfDay -> Word -> Text+timeShow (TimeOfDay hh mm seconds) precision =+    Text.pack (Printf.printf "%02d:%02d:%02d" hh mm ss <> suffix)+  where+    magnitude :: Integer+    magnitude = 10 ^ precision++    (ss, fraction) =+        truncate (seconds * fromInteger magnitude) `divMod` magnitude++    suffix+        | precision == 0 = ""+        | otherwise      = Printf.printf ".%0*d" precision fraction++-- | Utility that powers the @TimeZone/show@ built-in+timezoneShow :: TimeZone -> Text+timezoneShow = Text.pack . Time.formatTime Time.defaultTimeLocale "%Ez"+ conv :: forall a. Eq a => Environment a -> Val a -> Val a -> Bool conv !env t0 t0' =     case (t0, t0') of@@ -923,6 +993,10 @@             conv env t t' && conv env u u'         (VBoolIf t u v, VBoolIf t' u' v') ->             conv env t t' && conv env u u' && conv env v v'+        (VBytes, VBytes) ->+            True+        (VBytesLit l, VBytesLit r) ->+            l == r         (VNatural, VNatural) ->             True         (VNaturalLit n, VNaturalLit n') ->@@ -975,6 +1049,24 @@             conv env t t'         (VTextReplace a b c, VTextReplace a' b' c') ->             conv env a a' && conv env b b' && conv env c c'+        (VDate, VDate) ->+            True+        (VDateLiteral l, VDateLiteral r) ->+            l == r+        (VDateShow t, VDateShow t') ->+            conv env t t'+        (VTime, VTime) ->+            True+        (VTimeLiteral tl pl, VTimeLiteral tr pr) ->+            tl == tr && pl == pr+        (VTimeShow t, VTimeShow t') ->+            conv env t t'+        (VTimeZone, VTimeZone) ->+            True+        (VTimeZoneLiteral l, VTimeZoneLiteral r) ->+            l == r+        (VTimeZoneShow t, VTimeZoneShow t') ->+            conv env t t'         (VList a, VList a') ->             conv env a a'         (VListLit _ xs, VListLit _ xs') ->@@ -1017,6 +1109,8 @@             conv env t t' && conv env u u'         (VToMap t _, VToMap t' _) ->             conv env t t'+        (VShowConstructor t, VShowConstructor t') ->+            conv env t t'         (VField t k, VField t' k') ->             conv env t t' && k == k'         (VProject t (Left ks), VProject t' (Left ks')) ->@@ -1054,6 +1148,7 @@ judgmentallyEqual :: Eq a => Expr s a -> Expr t a -> Bool judgmentallyEqual (Syntax.denote -> t) (Syntax.denote -> u) =     conv Empty (eval Empty t) (eval Empty u)+{-# INLINABLE judgmentallyEqual #-}  data Names   = EmptyNames@@ -1083,21 +1178,29 @@             quote env t `qApp` u         VLam a (freshClosure -> (x, v, t)) ->             Lam+                mempty                 (Syntax.makeFunctionBinding x (quote env a))                 (quoteBind x (instantiate t v))         VHLam i t ->             case i of                 Typed (fresh -> (x, v)) a ->-                    Lam+                    Lam mempty                         (Syntax.makeFunctionBinding x (quote env a))                         (quoteBind x (t v))-                Prim                      -> quote env (t VPrimVar)-                NaturalSubtractZero       -> App NaturalSubtract (NaturalLit 0)+                Prim ->+                    quote env (t VPrimVar)+                NaturalSubtractZero ->+                    App NaturalSubtract (NaturalLit 0)+                TextReplaceEmpty ->+                    App TextReplace (TextLit (Chunks [] ""))+                TextReplaceEmptyArgument replacement ->+                    App (App TextReplace (TextLit (Chunks [] "")))+                        (quote env replacement)          VPi a (freshClosure -> (x, v, b)) ->-            Pi x (quote env a) (quoteBind x (instantiate b v))+            Pi mempty x (quote env a) (quoteBind x (instantiate b v))         VHPi (fresh -> (x, v)) a b ->-            Pi x (quote env a) (quoteBind x (b v))+            Pi mempty x (quote env a) (quoteBind x (b v))         VBool ->             Bool         VBoolLit b ->@@ -1112,6 +1215,10 @@             BoolNE (quote env t) (quote env u)         VBoolIf t u v ->             BoolIf (quote env t) (quote env u) (quote env v)+        VBytes ->+            Bytes+        VBytesLit b ->+            BytesLit b         VNatural ->             Natural         VNaturalLit n ->@@ -1164,6 +1271,24 @@             TextShow `qApp` t         VTextReplace a b c ->             TextReplace `qApp` a `qApp` b `qApp` c+        VDate ->+            Date+        VDateLiteral d ->+            DateLiteral d+        VDateShow t ->+            DateShow `qApp` t+        VTime ->+            Time+        VTimeLiteral t p ->+            TimeLiteral t p+        VTimeShow t ->+            TimeShow `qApp` t+        VTimeZone ->+            TimeZone+        VTimeZoneLiteral z ->+            TimeZoneLiteral z+        VTimeZoneShow t ->+            TimeZoneShow `qApp` t         VList t ->             List `qApp` t         VListLit ma ts ->@@ -1197,23 +1322,25 @@         VUnion m ->             Union (fmap (fmap (quote env)) m)         VCombine mk t u ->-            Combine mk (quote env t) (quote env u)+            Combine mempty mk (quote env t) (quote env u)         VCombineTypes t u ->-            CombineTypes (quote env t) (quote env u)+            CombineTypes mempty (quote env t) (quote env u)         VPrefer t u ->-            Prefer PreferFromSource (quote env t) (quote env u)+            Prefer mempty PreferFromSource (quote env t) (quote env u)         VMerge t u ma ->             Merge (quote env t) (quote env u) (fmap (quote env) ma)         VToMap t ma ->             ToMap (quote env t) (fmap (quote env) ma)+        VShowConstructor t ->+            ShowConstructor (quote env t)         VField t k ->             Field (quote env t) $ Syntax.makeFieldSelection k         VProject t p ->-            Project (quote env t) (fmap (quote env) p)+            Project (quote env t) (first Dhall.Set.toList (fmap (quote env) p))         VAssert t ->             Assert (quote env t)         VEquivalent t u ->-            Equivalent (quote env t) (quote env u)+            Equivalent mempty (quote env t) (quote env u)         VWith e ks v ->             With (quote env e) ks (quote env v)         VInject m k Nothing ->@@ -1253,6 +1380,7 @@  normalize :: Eq a => Expr s a -> Expr t a normalize = nf Empty+{-# INLINABLE normalize #-}  alphaNormalize :: Expr s a -> Expr s a alphaNormalize = goEnv EmptyNames@@ -1272,10 +1400,10 @@                 Const k             Var (V x i) ->                 goVar e0 x i-            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)+            Lam cs (FunctionBinding src0 x src1 src2 t) u ->+                Lam cs (FunctionBinding src0 "_" src1 src2 (go t)) (goBind x u)+            Pi cs x a b ->+                Pi cs "_" (go a) (goBind x b)             App t u ->                 App (go t) (go u)             Let (Binding src0 x src1 mA src2 a) b ->@@ -1296,6 +1424,10 @@                 BoolNE  (go t) (go u)             BoolIf b t f ->                 BoolIf  (go b) (go t) (go f)+            Bytes ->+                Bytes+            BytesLit b ->+                BytesLit b             Natural ->                 Natural             NaturalLit n ->@@ -1348,6 +1480,24 @@                 TextShow             TextReplace ->                 TextReplace+            Date ->+                Date+            DateLiteral d ->+                DateLiteral d+            DateShow ->+                DateShow+            Time ->+                Time+            TimeLiteral t p ->+                TimeLiteral t p+            TimeShow ->+                TimeShow+            TimeZone ->+                TimeZone+            TimeZoneLiteral z ->+                TimeZoneLiteral z+            TimeZoneShow ->+                TimeZoneShow             List ->                 List             ListLit ma ts ->@@ -1380,26 +1530,28 @@                 RecordLit (goRecordField <$> kts)             Union kts ->                 Union (fmap (fmap go) kts)-            Combine m t u ->-                Combine m (go t) (go u)-            CombineTypes t u ->-                CombineTypes (go t) (go u)-            Prefer b t u ->-                Prefer b (go t) (go u)+            Combine cs m t u ->+                Combine cs m (go t) (go u)+            CombineTypes cs t u ->+                CombineTypes cs (go t) (go u)+            Prefer cs b t u ->+                Prefer cs b (go t) (go u)             RecordCompletion t u ->                 RecordCompletion (go t) (go u)             Merge x y ma ->                 Merge (go x) (go y) (fmap go ma)             ToMap x ma ->                 ToMap (go x) (fmap go ma)+            ShowConstructor x ->+                ShowConstructor (go x)             Field t k ->                 Field (go t) k             Project t ks ->                 Project (go t) (fmap go ks)             Assert t ->                 Assert (go t)-            Equivalent t u ->-                Equivalent (go t) (go u)+            Equivalent cs t u ->+                Equivalent cs (go t) (go u)             With e k v ->                 With (go e) k (go v)             Note s e ->
src/Dhall/Format.hs view
@@ -9,78 +9,83 @@     , format     ) where -import Data.Foldable (for_)-import Dhall.Pretty  (CharacterSet (..), annToAnsiStyle)-+import Data.Foldable      (for_)+import Data.List.NonEmpty (NonEmpty)+import Data.Maybe         (fromMaybe)+import Dhall.Pretty       (CharacterSet, annToAnsiStyle, detectCharacterSet) import Dhall.Util     ( Censor     , CheckFailed (..)     , Header (..)+    , Input (..)     , OutputMode (..)-    , PossiblyTransitiveInput (..)     , Transitivity (..)+    , handleMultipleChecksFailed     ) -import qualified Control.Exception import qualified Data.Text.IO-import qualified Data.Text.Prettyprint.Doc                 as Pretty-import qualified Data.Text.Prettyprint.Doc.Render.Terminal as Pretty.Terminal-import qualified Data.Text.Prettyprint.Doc.Render.Text     as Pretty.Text import qualified Dhall.Import import qualified Dhall.Pretty import qualified Dhall.Util-import qualified System.AtomicWrite.Writer.LazyText        as AtomicWrite.LazyText+import qualified Prettyprinter                      as Pretty+import qualified Prettyprinter.Render.Terminal      as Pretty.Terminal+import qualified Prettyprinter.Render.Text          as Pretty.Text+import qualified System.AtomicWrite.Writer.LazyText as AtomicWrite.LazyText import qualified System.Console.ANSI import qualified System.FilePath import qualified System.IO  -- | Arguments to the `format` subcommand data Format = Format-    { characterSet :: CharacterSet-    , censor       :: Censor-    , input        :: PossiblyTransitiveInput-    , outputMode   :: OutputMode+    { chosenCharacterSet :: Maybe CharacterSet+    , censor             :: Censor+    , transitivity       :: Transitivity+    , inputs             :: NonEmpty Input+    , outputMode         :: OutputMode     }  -- | Implementation of the @dhall format@ subcommand format :: Format -> IO ()-format (Format { input = input0, ..}) = go input0+format (Format { inputs = inputs0, transitivity = transitivity0, ..}) =+    handleMultipleChecksFailed "format" "formatted" go inputs0   where     go input = do         let directory = case input of-                NonTransitiveStandardInput ->+                StandardInput ->                     "."-                PossiblyTransitiveInputFile file _ ->+                InputFile file ->                     System.FilePath.takeDirectory file          let status = Dhall.Import.emptyStatus directory          let layoutHeaderAndExpr (Header header, expr) =+                let characterSet = fromMaybe (detectCharacterSet expr) chosenCharacterSet+                in                 Dhall.Pretty.layout                     (   Pretty.pretty header                     <>  Dhall.Pretty.prettyCharacterSet characterSet expr                     <>  "\n") -        (originalText, transitivity) <- case input of-            PossiblyTransitiveInputFile file transitivity -> do+        (inputName, originalText, transitivity) <- case input of+            InputFile file -> do                 text <- Data.Text.IO.readFile file -                return (text, transitivity)--            NonTransitiveStandardInput -> do+                return (file, text, transitivity0)+            StandardInput -> do                 text <- Data.Text.IO.getContents -                return (text, NonTransitive)+                return ("(input)", text, NonTransitive) -        headerAndExpr@(_, parsedExpression) <- Dhall.Util.getExpressionAndHeaderFromStdinText censor originalText +        headerAndExpr@(_, parsedExpression) <- Dhall.Util.getExpressionAndHeaderFromStdinText censor inputName originalText+         case transitivity of             Transitive ->                 for_ parsedExpression $ \import_ -> do                     maybeFilepath <- Dhall.Import.dependencyToFile status import_                      for_ maybeFilepath $ \filepath ->-                        go (PossiblyTransitiveInputFile filepath Transitive)+                        go (InputFile filepath)              NonTransitive ->                 return ()@@ -90,16 +95,16 @@         let formattedText = Pretty.Text.renderStrict docStream          case outputMode of-            Write ->+            Write -> do                 case input of-                    PossiblyTransitiveInputFile file _ ->+                    InputFile file ->                         if originalText == formattedText                             then return ()                             else AtomicWrite.LazyText.atomicWriteFile                                     file                                     (Pretty.Text.renderLazy docStream) -                    NonTransitiveStandardInput -> do+                    StandardInput -> do                         supportsANSI <- System.Console.ANSI.hSupportsANSI System.IO.stdout                          Pretty.Terminal.renderIO@@ -108,12 +113,10 @@                                 then (fmap annToAnsiStyle docStream)                                 else (Pretty.unAnnotateS docStream)) -            Check ->-                if originalText == formattedText-                    then return ()-                    else do-                        let command = "format"--                        let modified = "formatted"+                return (Right ()) -                        Control.Exception.throwIO CheckFailed{..}+            Check ->+                return $+                    if originalText == formattedText+                        then Right ()+                        else Left CheckFailed{..}
src/Dhall/Freeze.hs view
@@ -1,5 +1,5 @@-{-# LANGUAGE NamedFieldPuns    #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes        #-} {-# LANGUAGE RecordWildCards   #-} {-# LANGUAGE ViewPatterns      #-} @@ -8,21 +8,32 @@ module Dhall.Freeze     ( -- * Freeze       freeze-    , freezeWithManager     , freezeExpression-    , freezeExpressionWithManager     , freezeImport-    , freezeImportWithManager     , freezeRemoteImport-    , freezeRemoteImportWithManager +      -- * Freeze with custom evaluation settings+    , freezeWithSettings+    , freezeExpressionWithSettings+    , freezeImportWithSettings+    , freezeRemoteImportWithSettings+       -- * Types     , Scope(..)     , Intent(..)++      -- * Deprecated functions+    , freezeWithManager+    , freezeExpressionWithManager+    , freezeImportWithManager+    , freezeRemoteImportWithManager     ) where  import Data.Foldable       (for_)-import Dhall.Pretty        (CharacterSet)+import Data.List.NonEmpty  (NonEmpty)+import Data.Maybe          (fromMaybe)+import Dhall               (EvaluateSettings)+import Dhall.Pretty        (CharacterSet, detectCharacterSet) import Dhall.Syntax     ( Expr (..)     , Import (..)@@ -33,35 +44,56 @@     ( Censor     , CheckFailed (..)     , Header (..)+    , Input (..)     , OutputMode (..)-    , PossiblyTransitiveInput (..)     , Transitivity (..)+    , handleMultipleChecksFailed     )+import Lens.Micro          (set, transformMOf, transformOf)+import Lens.Micro.Extras   (view) import System.Console.ANSI (hSupportsANSI) -import qualified Control.Exception                         as Exception-import qualified Control.Monad.Trans.State.Strict          as State-import qualified Data.Text.IO                              as Text.IO-import qualified Data.Text.Prettyprint.Doc                 as Pretty-import qualified Data.Text.Prettyprint.Doc.Render.Terminal as Pretty-import qualified Data.Text.Prettyprint.Doc.Render.Text     as Pretty.Text-import qualified Dhall.Core                                as Core+import qualified Control.Exception                  as Exception+import qualified Control.Monad.Trans.State.Strict   as State+import qualified Data.Text.IO                       as Text.IO+import qualified Dhall+import qualified Dhall.Core                         as Core import qualified Dhall.Import-import qualified Dhall.Optics import qualified Dhall.Pretty import qualified Dhall.TypeCheck-import qualified Dhall.Util                                as Util-import qualified System.AtomicWrite.Writer.LazyText        as AtomicWrite.LazyText+import qualified Dhall.Util                         as Util+import qualified Prettyprinter                      as Pretty+import qualified Prettyprinter.Render.Terminal      as Pretty+import qualified Prettyprinter.Render.Text          as Pretty.Text+import qualified System.AtomicWrite.Writer.LazyText as AtomicWrite.LazyText import qualified System.FilePath import qualified System.IO +-- | Specifies which imports to freeze+data Scope+    = OnlyRemoteImports+    -- ^ Freeze only remote imports (i.e. URLs)+    | AllImports+    -- ^ Freeze all imports (including paths and environment variables)++-- | Specifies why we are adding semantic integrity checks+data Intent+    = Secure+    -- ^ Protect imports with an integrity check without a fallback so that+    --   import resolution fails if the import changes+    | Cache+    -- ^ Protect imports with an integrity check and also add a fallback import+    --   import without an integrity check.  This is useful if you only want to+    --   cache imports when possible but still gracefully degrade to resolving+    --   them if the semantic integrity check has changed.+ -- | Retrieve an `Import` and update the hash to match the latest contents freezeImport     :: FilePath     -- ^ Current working directory     -> Import     -> IO Import-freezeImport = freezeImportWithManager Dhall.Import.defaultNewManager+freezeImport = freezeImportWithSettings Dhall.defaultEvaluateSettings  -- | See 'freezeImport'. freezeImportWithManager@@ -69,7 +101,88 @@     -> FilePath     -> Import     -> IO Import-freezeImportWithManager newManager directory import_ = do+freezeImportWithManager newManager = freezeImportWithSettings (set Dhall.newManager newManager Dhall.defaultEvaluateSettings)+{-# DEPRECATED freezeImportWithManager "Use freezeImportWithSettings directly" #-}++-- | Freeze an import only if the import is a `Remote` import+freezeRemoteImport+    :: FilePath+    -- ^ Current working directory+    -> Import+    -> IO Import+freezeRemoteImport = freezeRemoteImportWithSettings Dhall.defaultEvaluateSettings++-- | See 'freezeRemoteImport'.+freezeRemoteImportWithManager+    :: IO Dhall.Import.Manager+    -> FilePath+    -> Import+    -> IO Import+freezeRemoteImportWithManager newManager = freezeRemoteImportWithSettings (set Dhall.newManager newManager Dhall.defaultEvaluateSettings)+{-# DEPRECATED freezeRemoteImportWithManager "Use freezeRemoteImportWithSettings directly" #-}++-- | Implementation of the @dhall freeze@ subcommand+freeze+    :: OutputMode+    -> Transitivity+    -> NonEmpty Input+    -> Scope+    -> Intent+    -> Maybe CharacterSet+    -> Censor+    -> IO ()+freeze = freezeWithSettings Dhall.defaultEvaluateSettings++-- | See 'freeze'.+freezeWithManager+    :: IO Dhall.Import.Manager+    -> OutputMode+    -> Transitivity+    -> NonEmpty Input+    -> Scope+    -> Intent+    -> Maybe CharacterSet+    -> Censor+    -> IO ()+freezeWithManager newManager = freezeWithSettings (set Dhall.newManager newManager Dhall.defaultEvaluateSettings)+{-# DEPRECATED freezeWithManager "Use freezeWithSettings directly" #-}++{-| Slightly more pure version of the `freeze` function++    This still requires `IO` to freeze the import, but now the input and output+    expression are passed in explicitly+-}+freezeExpression+    :: FilePath+    -- ^ Starting directory+    -> Scope+    -> Intent+    -> Expr s Import+    -> IO (Expr s Import)+freezeExpression = freezeExpressionWithSettings Dhall.defaultEvaluateSettings++-- | See 'freezeExpression'.+freezeExpressionWithManager+    :: IO Dhall.Import.Manager+    -> FilePath+    -> Scope+    -> Intent+    -> Expr s Import+    -> IO (Expr s Import)+freezeExpressionWithManager newManager = freezeExpressionWithSettings (set Dhall.newManager newManager Dhall.defaultEvaluateSettings)+{-# DEPRECATED freezeExpressionWithManager "Use freezeExpressionWithSettings directly" #-}++--------------------------------------------------------------------------------+-- Versions that take EvaluateSettings+--------------------------------------------------------------------------------++-- | See 'freezeImport'.+freezeImportWithSettings+    :: EvaluateSettings+    -> FilePath+    -> Import+    -> IO Import+freezeImportWithSettings settings directory import_ = do     let unprotectedImport =             import_                 { importHashed =@@ -78,15 +191,15 @@                         }                 } -    let status = Dhall.Import.emptyStatusWithManager newManager directory+    let status = Dhall.Import.emptyStatusWithManager (view Dhall.newManager settings) directory      expression <- State.evalStateT (Dhall.Import.loadWith (Embed unprotectedImport)) status -    case Dhall.TypeCheck.typeOf expression of+    case Dhall.TypeCheck.typeWith (view Dhall.startingContext settings) expression of         Left  exception -> Exception.throwIO exception         Right _         -> return () -    let normalizedExpression = Core.alphaNormalize (Core.normalize expression)+    let normalizedExpression = Core.alphaNormalize (Core.normalizeWith (view Dhall.normalizer settings) expression)      -- make sure the frozen import is present in the semantic cache     Dhall.Import.writeExpressionToSemanticCache (Core.denote expression)@@ -99,100 +212,78 @@      return newImport --- | Freeze an import only if the import is a `Remote` import-freezeRemoteImport-    :: FilePath-    -- ^ Current working directory+-- | See 'freezeRemoteImport'.+freezeRemoteImportWithSettings+    :: EvaluateSettings+    -> FilePath     -> Import     -> IO Import-freezeRemoteImport = freezeRemoteImportWithManager Dhall.Import.defaultNewManager+freezeRemoteImportWithSettings settings directory import_ =+    case importType (importHashed import_) of+        Remote {} -> freezeImportWithSettings settings directory import_+        _         -> return import_  -- | See 'freezeRemoteImport'.-freezeRemoteImportWithManager-    :: IO Dhall.Import.Manager+freezeNonMissingImportWithSettings+    :: EvaluateSettings     -> FilePath     -> Import     -> IO Import-freezeRemoteImportWithManager newManager directory import_ =+freezeNonMissingImportWithSettings settings directory import_ =     case importType (importHashed import_) of-        Remote {} -> freezeImportWithManager newManager directory import_-        _         -> return import_---- | Specifies which imports to freeze-data Scope-    = OnlyRemoteImports-    -- ^ Freeze only remote imports (i.e. URLs)-    | AllImports-    -- ^ Freeze all imports (including paths and environment variables)---- | Specifies why we are adding semantic integrity checks-data Intent-    = Secure-    -- ^ Protect imports with an integrity check without a fallback so that-    --   import resolution fails if the import changes-    | Cache-    -- ^ Protect imports with an integrity check and also add a fallback import-    --   import without an integrity check.  This is useful if you only want to-    --   cache imports when possible but still gracefully degrade to resolving-    --   them if the semantic integrity check has changed.---- | Implementation of the @dhall freeze@ subcommand-freeze-    :: OutputMode-    -> PossiblyTransitiveInput-    -> Scope-    -> Intent-    -> CharacterSet-    -> Censor-    -> IO ()-freeze = freezeWithManager Dhall.Import.defaultNewManager+        Missing -> return import_+        _ -> freezeImportWithSettings settings directory import_  -- | See 'freeze'.-freezeWithManager-    :: IO Dhall.Import.Manager+freezeWithSettings+    :: EvaluateSettings     -> OutputMode-    -> PossiblyTransitiveInput+    -> Transitivity+    -> NonEmpty Input     -> Scope     -> Intent-    -> CharacterSet+    -> Maybe CharacterSet     -> Censor     -> IO ()-freezeWithManager newManager outputMode input0 scope intent characterSet censor = go input0+freezeWithSettings settings outputMode transitivity0 inputs scope intent chosenCharacterSet censor =+    handleMultipleChecksFailed "freeze" "frozen" go inputs   where     go input = do         let directory = case input of-                NonTransitiveStandardInput ->+                StandardInput ->                     "."-                PossiblyTransitiveInputFile file _ ->+                InputFile file ->                     System.FilePath.takeDirectory file -        let status = Dhall.Import.emptyStatusWithManager newManager directory+        let status = Dhall.Import.emptyStatusWithManager (view Dhall.newManager settings) directory -        (originalText, transitivity) <- case input of-            PossiblyTransitiveInputFile file transitivity -> do+        (inputName, originalText, transitivity) <- case input of+            InputFile file -> do                 text <- Text.IO.readFile file -                return (text, transitivity)+                return (file, text, transitivity0) -            NonTransitiveStandardInput -> do+            StandardInput -> do                 text <- Text.IO.getContents -                return (text, NonTransitive)+                return ("(input)", text, NonTransitive) -        (Header header, parsedExpression) <- Util.getExpressionAndHeaderFromStdinText censor originalText+        (Header header, parsedExpression) <- Util.getExpressionAndHeaderFromStdinText censor inputName originalText +        let characterSet = fromMaybe (detectCharacterSet parsedExpression) chosenCharacterSet+         case transitivity of             Transitive ->                 for_ parsedExpression $ \import_ -> do                     maybeFilepath <- Dhall.Import.dependencyToFile status import_                      for_ maybeFilepath $ \filepath ->-                        go (PossiblyTransitiveInputFile filepath Transitive)+                        go (InputFile filepath)              NonTransitive ->                 return () -        frozenExpression <- freezeExpressionWithManager newManager directory scope intent parsedExpression+        frozenExpression <- freezeExpressionWithSettings settings directory scope intent parsedExpression          let doc =  Pretty.pretty header                 <> Dhall.Pretty.prettyCharacterSet characterSet frozenExpression@@ -207,7 +298,7 @@                 let unAnnotated = Pretty.unAnnotateS stream                  case input of-                    PossiblyTransitiveInputFile file _ ->+                    InputFile file ->                         if originalText == modifiedText                             then return ()                             else@@ -215,7 +306,7 @@                                     file                                     (Pretty.Text.renderLazy unAnnotated) -                    NonTransitiveStandardInput -> do+                    StandardInput -> do                         supportsANSI <- System.Console.ANSI.hSupportsANSI System.IO.stdout                         if supportsANSI                            then@@ -223,45 +314,29 @@                            else                              Pretty.renderIO System.IO.stdout unAnnotated -            Check ->-                if originalText == modifiedText-                    then return ()-                    else do-                        let command = "freeze"--                        let modified = "frozen"--                        Exception.throwIO CheckFailed{..}--{-| Slightly more pure version of the `freeze` function+                return (Right ()) -    This still requires `IO` to freeze the import, but now the input and output-    expression are passed in explicitly--}-freezeExpression-    :: FilePath-    -- ^ Starting directory-    -> Scope-    -> Intent-    -> Expr s Import-    -> IO (Expr s Import)-freezeExpression = freezeExpressionWithManager Dhall.Import.defaultNewManager+            Check ->+                return $+                    if originalText == modifiedText+                        then Right ()+                        else Left CheckFailed{..}  -- | See 'freezeExpression'.-freezeExpressionWithManager-    :: IO Dhall.Import.Manager+freezeExpressionWithSettings+    :: EvaluateSettings     -> FilePath     -> Scope     -> Intent     -> Expr s Import     -> IO (Expr s Import)-freezeExpressionWithManager newManager directory scope intent expression = do+freezeExpressionWithSettings settings directory scope intent expression = do     let freezeScope =             case scope of-                AllImports        -> freezeImportWithManager-                OnlyRemoteImports -> freezeRemoteImportWithManager+                AllImports        -> freezeNonMissingImportWithSettings+                OnlyRemoteImports -> freezeRemoteImportWithSettings -    let freezeFunction = freezeScope newManager directory+    let freezeFunction = freezeScope settings directory      let cache             -- This case is necessary because `transformOf` is a bottom-up@@ -309,17 +384,21 @@             (Embed import_@(Import { importHashed = ImportHashed { hash = Nothing } })) = do                 frozenImport <- freezeFunction import_ +                let frozenMissing = toMissing frozenImport+                 {- The two imports can be the same if the import is local and                    `freezeFunction` only freezes remote imports by default                 -}                 if frozenImport /= import_-                    then return (ImportAlt (Embed frozenImport) (Embed import_))+                    then return (ImportAlt (Embed frozenMissing) (Embed import_))                     else return (Embed import_)         cache             (Embed import_@(Import { importHashed = ImportHashed { hash = Just _ } })) = do                 -- Regenerate the integrity check, just in case it's wrong                 frozenImport <- freezeFunction import_ +                let frozenMissing = toMissing frozenImport+                 -- `dhall freeze --cache` also works the other way around, adding an                 -- unprotected fallback import to imports that are already                 -- protected@@ -329,12 +408,38 @@                             }                         } -                return (ImportAlt (Embed frozenImport) (Embed thawedImport))+                return (ImportAlt (Embed frozenMissing) (Embed thawedImport))         cache expression_ =             return expression_ -    case intent of+    let uncache+            (ImportAlt+                (Core.shallowDenote -> Embed+                    Import{ importHashed = ImportHashed { hash = Just expectedHash, importType = Missing } }+                )+                (Core.shallowDenote -> Embed+                    import_@Import{ importHashed = ImportHashed{ hash = Nothing } }+                )+            ) = Embed+                (import_+                    { importHashed = (importHashed import_)+                        { hash = Just expectedHash+                        }+                    }+                )+        uncache expression_ = expression_++    let simplify (ImportAlt (Core.shallowDenote -> Embed import1) (Core.shallowDenote -> Embed import2))+            | import1 == import2 = Embed import1+        simplify expression_ = expression_++    transformOf Core.subExpressions simplify <$> case intent of         Secure ->-            traverse freezeFunction expression+            traverse freezeFunction (transformOf Core.subExpressions uncache expression)         Cache  ->-            Dhall.Optics.transformMOf Core.subExpressions cache expression+            transformMOf Core.subExpressions cache expression++-- https://github.com/dhall-lang/dhall-haskell/issues/2347+toMissing :: Import -> Import+toMissing import_ =+    import_ { importHashed = (importHashed import_) { importType = Missing } }
src/Dhall/Import.hs view
@@ -1,12 +1,14 @@+{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE CPP                 #-} {-# LANGUAGE DeriveAnyClass      #-} {-# LANGUAGE DeriveDataTypeable  #-}+{-# LANGUAGE FlexibleContexts    #-} {-# LANGUAGE NamedFieldPuns      #-} {-# LANGUAGE OverloadedStrings   #-} {-# LANGUAGE RankNTypes          #-} {-# LANGUAGE RecordWildCards     #-} {-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE ViewPatterns        #-}+{-# LANGUAGE TypeApplications    #-}  {-# OPTIONS_GHC -Wall #-} @@ -105,16 +107,16 @@       load     , loadWithManager     , loadRelativeTo-    , loadRelativeToWithManager+    , loadWithStatus     , loadWith     , localToPath     , hashExpression     , hashExpressionToCode     , writeExpressionToSemanticCache-    , warnAboutMissingCaches     , assertNoImports     , Manager     , defaultNewManager+    , CacheWarning(..)     , Status(..)     , SemanticCacheMode(..)     , Chained@@ -123,6 +125,11 @@     , chainedChangeMode     , emptyStatus     , emptyStatusWithManager+    , envOriginHeaders+    , makeEmptyStatus+    , remoteStatus+    , remoteStatusWithManager+    , fetchRemote     , stack     , cache     , Depends(..)@@ -147,26 +154,25 @@     , HashMismatch(..)     ) where -import Control.Applicative              (Alternative (..), liftA2)+import Control.Applicative        (Alternative (..)) import Control.Exception     ( Exception     , IOException     , SomeException     , toException     )-import Control.Monad                    (when)-import Control.Monad.Catch              (MonadCatch (catch), handle, throwM)-import Control.Monad.IO.Class           (MonadIO (..))-import Control.Monad.Morph              (hoist)-import Control.Monad.Trans.Class        (lift)-import Control.Monad.Trans.State.Strict (StateT)-import Data.ByteString                  (ByteString)-import Data.CaseInsensitive             (CI)-import Data.List.NonEmpty               (NonEmpty (..))-import Data.Text                        (Text)-import Data.Typeable                    (Typeable)-import Data.Void                        (Void, absurd)-import Dhall.Binary                     (StandardVersion (..))+import Control.Monad.Catch        (MonadCatch (catch), handle, throwM)+import Control.Monad.IO.Class     (MonadIO (..))+import Control.Monad.Morph        (hoist)+import Control.Monad.State.Strict (MonadState, StateT)+import Data.ByteString            (ByteString)+import Data.List.NonEmpty         (NonEmpty (..), nonEmpty)+import Data.Maybe                 (fromMaybe)+import Data.Text                  (Text)+import Data.Typeable              (Typeable)+import Data.Void                  (Void, absurd)+import Dhall.TypeCheck            (TypeError)+import Dhall.Util                 (printWarning)  import Dhall.Syntax     ( Chunks (..)@@ -185,10 +191,17 @@     )  import System.FilePath ((</>))+import Text.Megaparsec (SourcePos (SourcePos), mkPos)  #ifdef WITH_HTTP import Dhall.Import.HTTP #endif+import Dhall.Import.Headers+    ( normalizeHeaders+    , originHeadersTypeExpr+    , toHeaders+    , toOriginHeaders+    ) import Dhall.Import.Types  import Dhall.Parser@@ -197,20 +210,19 @@     , SourcedException (..)     , Src (..)     )-import Lens.Family.State.Strict (zoom)+import Lens.Micro.Mtl (zoom) -import qualified Codec.CBOR.Encoding                         as Encoding import qualified Codec.CBOR.Write                            as Write import qualified Codec.Serialise+import qualified Control.Exception                           as Exception+import qualified Control.Monad.State.Strict                  as State import qualified Control.Monad.Trans.Maybe                   as Maybe-import qualified Control.Monad.Trans.State.Strict            as State import qualified Data.ByteString import qualified Data.ByteString.Lazy-import qualified Data.CaseInsensitive-import qualified Data.Foldable import qualified Data.List.NonEmpty                          as NonEmpty+import qualified Data.Maybe                                  as Maybe import qualified Data.Text                                   as Text-import qualified Data.Text.Encoding+import qualified Data.Text.Encoding                          as Encoding import qualified Data.Text.IO import qualified Dhall.Binary import qualified Dhall.Core                                  as Core@@ -282,7 +294,7 @@  instance Show ReferentiallyOpaque where     show (ReferentiallyOpaque import_) =-        "\nReferentially opaque import: " ++ Dhall.Pretty.Internal.prettyToString import_+        "\nLocal imports are not permitted from remote imports: " ++ Dhall.Pretty.Internal.prettyToString import_  -- | Extend another exception with the current import stack data Imported e = Imported@@ -351,9 +363,6 @@ 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 -- the @with-http@ Cabal flag. data CannotImportHTTPURL =@@ -497,7 +506,7 @@ -- | Chain imports, also typecheck and normalize headers if applicable. chainImport :: Chained -> Import -> StateT Status IO Chained chainImport (Chained parent) child@(Import importHashed@(ImportHashed _ (Remote url)) _) = do-    url' <- normalizeHeaders url+    url' <- normalizeHeadersIn url     let child' = child { importHashed = importHashed { importType = Remote url' } }     return (Chained (canonicalize (parent <> child'))) @@ -536,8 +545,10 @@     Status { .. } <- State.get     mCached <-         case _semanticCacheMode of-            UseSemanticCache -> liftIO $ fetchFromSemanticCache semanticHash-            IgnoreSemanticCache -> pure Nothing+            UseSemanticCache ->+                zoom cacheWarning (fetchFromSemanticCache semanticHash)+            IgnoreSemanticCache ->+                pure Nothing      case mCached of         Just bytesStrict -> do@@ -563,24 +574,32 @@         Nothing -> fetch     where         fetch = do-            ImportSemantics { importSemantics } <- loadImportWithSemisemanticCache import_+            ImportSemantics{ importSemantics } <- loadImportWithSemisemanticCache import_ -            let variants = map (\version -> encodeExpression version (Core.alphaNormalize importSemantics))-                                [ minBound .. maxBound ]-            case Data.Foldable.find ((== semanticHash). Dhall.Crypto.sha256Hash) variants of-                Just bytes -> liftIO $ writeToSemanticCache semanticHash bytes-                Nothing -> do-                    let expectedHash = semanticHash-                    Status { _stack } <- State.get-                    let actualHash = hashExpression (Core.alphaNormalize importSemantics)-                    throwMissingImport (Imported _stack (HashMismatch {..}))+            let bytes = encodeExpression (Core.alphaNormalize importSemantics) -            return (ImportSemantics {..})+            let actualHash = Dhall.Crypto.sha256Hash bytes +            let expectedHash = semanticHash +            if actualHash == expectedHash+                then do+                    zoom cacheWarning (writeToSemanticCache semanticHash bytes) +                else do+                    Status{ _stack } <- State.get++                    throwMissingImport (Imported _stack HashMismatch{..})++            return ImportSemantics{..}+++ -- Fetch encoded normal form from "semantic cache"-fetchFromSemanticCache :: Dhall.Crypto.SHA256Digest -> IO (Maybe Data.ByteString.ByteString)+fetchFromSemanticCache+    :: (MonadState CacheWarning m, MonadCatch m, MonadIO m)+    => Dhall.Crypto.SHA256Digest+    -> m (Maybe Data.ByteString.ByteString) fetchFromSemanticCache expectedHash = Maybe.runMaybeT $ do     cacheFile <- getCacheFile "dhall" expectedHash     True <- liftIO (Directory.doesFileExist cacheFile)@@ -589,12 +608,20 @@ -- | Ensure that the given expression is present in the semantic cache. The --   given expression should be alpha-beta-normal. writeExpressionToSemanticCache :: Expr Void Void -> IO ()-writeExpressionToSemanticCache expression = writeToSemanticCache hash bytes+writeExpressionToSemanticCache expression =+    -- Defaulting to not displaying the warning is for backwards compatibility+    -- with the old behavior+    State.evalStateT (writeToSemanticCache hash bytes) CacheWarned   where-    bytes = encodeExpression NoVersion expression+    bytes = encodeExpression expression+     hash = Dhall.Crypto.sha256Hash bytes -writeToSemanticCache :: Dhall.Crypto.SHA256Digest -> Data.ByteString.ByteString -> IO ()+writeToSemanticCache+    :: (MonadState CacheWarning m, MonadCatch m, MonadIO m)+    => Dhall.Crypto.SHA256Digest+    -> Data.ByteString.ByteString+    -> m () writeToSemanticCache hash bytes = do     _ <- Maybe.runMaybeT $ do         cacheFile <- getCacheFile "dhall" hash@@ -637,8 +664,9 @@     -- https://github.com/dhall-lang/dhall-haskell/issues/1098 for the reasoning     -- behind semi-semantic caching.     let semisemanticHash = computeSemisemanticHash (Core.denote resolvedExpr)-    mCached <- lift $ fetchFromSemisemanticCache semisemanticHash +    mCached <- zoom cacheWarning (fetchFromSemisemanticCache semisemanticHash)+     importSemantics <- case mCached of         Just bytesStrict -> do             let bytesLazy = Data.ByteString.Lazy.fromStrict bytesStrict@@ -668,23 +696,29 @@                     let betaNormal =                             Core.normalizeWith _normalizer substitutedExpr -                    let bytes = encodeExpression NoVersion betaNormal+                    let bytes = encodeExpression betaNormal -                    lift (writeToSemisemanticCache semisemanticHash bytes)+                    zoom cacheWarning (writeToSemisemanticCache semisemanticHash bytes)                      return betaNormal      return (ImportSemantics {..}) --- `as Text` imports aren't cached since they are well-typed and normal by--- construction+-- `as Text` and `as Bytes` imports aren't cached since they are well-typed and+-- normal by construction loadImportWithSemisemanticCache (Chained (Import (ImportHashed _ importType) RawText)) = do     text <- fetchFresh importType      -- importSemantics is alpha-beta-normal by construction!     let importSemantics = TextLit (Chunks [] text)     return (ImportSemantics {..})+loadImportWithSemisemanticCache (Chained (Import (ImportHashed _ importType) RawBytes)) = do+    bytes <- fetchBytes importType +    -- importSemantics is alpha-beta-normal by construction!+    let importSemantics = BytesLit bytes+    return (ImportSemantics {..})+ -- `as Location` imports aren't cached since they are well-typed and normal by -- construction loadImportWithSemisemanticCache (Chained (Import (ImportHashed _ importType) Location)) = do@@ -718,20 +752,27 @@ computeSemisemanticHash resolvedExpr = hashExpression resolvedExpr  -- Fetch encoded normal form from "semi-semantic cache"-fetchFromSemisemanticCache :: Dhall.Crypto.SHA256Digest -> IO (Maybe Data.ByteString.ByteString)+fetchFromSemisemanticCache+    :: (MonadState CacheWarning m, MonadCatch m, MonadIO m)+    => Dhall.Crypto.SHA256Digest+    -> m (Maybe Data.ByteString.ByteString) fetchFromSemisemanticCache semisemanticHash = Maybe.runMaybeT $ do     cacheFile <- getCacheFile "dhall-haskell" semisemanticHash     True <- liftIO (Directory.doesFileExist cacheFile)     liftIO (Data.ByteString.readFile cacheFile) -writeToSemisemanticCache :: Dhall.Crypto.SHA256Digest -> Data.ByteString.ByteString -> IO ()+writeToSemisemanticCache+    :: (MonadState CacheWarning m, MonadCatch m, MonadIO m)+    => Dhall.Crypto.SHA256Digest+    -> Data.ByteString.ByteString+    -> m () writeToSemisemanticCache semisemanticHash bytes = do     _ <- Maybe.runMaybeT $ do         cacheFile <- getCacheFile "dhall-haskell" semisemanticHash         liftIO (AtomicWrite.Binary.atomicWriteFile cacheFile bytes)     return () --- Fetch source code directly from disk/network+-- | Fetch source code directly from disk/network fetchFresh :: ImportType -> StateT Status IO Text fetchFresh (Local prefix file) = do     Status { _stack } <- State.get@@ -756,7 +797,31 @@  fetchFresh Missing = throwM (MissingImports []) +-- | Like `fetchFresh`, except for `Dhall.Syntax.Expr.Bytes`+fetchBytes :: ImportType -> StateT Status IO ByteString+fetchBytes (Local prefix file) = do+    Status { _stack } <- State.get+    path <- liftIO $ localToPath prefix file+    exists <- liftIO $ Directory.doesFileExist path+    if exists+        then liftIO $ Data.ByteString.readFile path+        else throwMissingImport (Imported _stack (MissingFile path)) +fetchBytes (Remote url) = do+    Status { _remoteBytes } <- State.get+    _remoteBytes url++fetchBytes (Env env) = do+    Status { _stack } <- State.get+    x <- liftIO $ System.Environment.lookupEnv (Text.unpack env)+    case x of+        Just string ->+            return (Encoding.encodeUtf8 (Text.pack string))+        Nothing ->+            throwMissingImport (Imported _stack (MissingEnvironmentVariable env))+fetchBytes Missing = throwM (MissingImports [])++-- | Fetch the text contents of a URL fetchRemote :: URL -> StateT Status IO Data.Text.Text #ifndef WITH_HTTP fetchRemote (url@URL { headers = maybeHeadersExpression }) = do@@ -775,48 +840,48 @@         fetchFromHttpUrl url' maybeHeaders #endif --- | Given a well-typed (of type `List { header : Text, value Text }` or--- `List { mapKey : Text, mapValue Text }`) headers expressions in normal form--- construct the corresponding binary http headers; otherwise return the empty--- list.-toHeaders :: Expr s a -> [HTTPHeader]-toHeaders (ListLit _ hs) = Data.Foldable.toList (Data.Foldable.fold maybeHeaders)+-- | Fetch the text contents of a URL+fetchRemoteBytes :: URL -> StateT Status IO Data.ByteString.ByteString+#ifndef WITH_HTTP+fetchRemoteBytes (url@URL { headers = maybeHeadersExpression }) = do+    let maybeHeaders = fmap toHeaders maybeHeadersExpression+    let urlString = Text.unpack (Core.pretty url)+    Status { _stack } <- State.get+    throwMissingImport (Imported _stack (CannotImportHTTPURL urlString maybeHeaders))+#else+fetchRemoteBytes url = do+    zoom remoteBytes (State.put fetchFromHTTP)+    fetchFromHTTP url   where-      maybeHeaders = mapM toHeader hs-toHeaders _ = []--toHeader :: Expr s a -> Maybe HTTPHeader-toHeader (RecordLit m) = do-    (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-    return (Data.CaseInsensitive.mk keyBytes, valueBytes)-      where-        lookupHeader = liftA2 (,) (Dhall.Map.lookup "header" m) (Dhall.Map.lookup "value" m)-        lookupMapKey = liftA2 (,) (Dhall.Map.lookup "mapKey" m) (Dhall.Map.lookup "mapValue" m)-toHeader _ =-    empty+    fetchFromHTTP :: URL -> StateT Status IO Data.ByteString.ByteString+    fetchFromHTTP (url'@URL { headers = maybeHeadersExpression }) = do+        let maybeHeaders = fmap toHeaders maybeHeadersExpression+        fetchFromHttpUrlBytes url' maybeHeaders+#endif  getCacheFile-    :: (MonadCatch m, Alternative m, MonadIO m) => FilePath -> Dhall.Crypto.SHA256Digest -> m FilePath+    :: (MonadCatch m, Alternative m, MonadState CacheWarning m, MonadIO m)+    => FilePath -> Dhall.Crypto.SHA256Digest -> m FilePath getCacheFile cacheName hash = do-    cacheDirectory <- getOrCreateCacheDirectory False cacheName+    cacheDirectory <- getOrCreateCacheDirectory cacheName      let cacheFile = cacheDirectory </> ("1220" <> show hash)      return cacheFile --- | Warn if no cache directory is available-warnAboutMissingCaches :: (MonadCatch m, Alternative m, MonadIO m) => m ()-warnAboutMissingCaches = warn <|> return ()-    where warn = Data.Foldable.traverse_ (getOrCreateCacheDirectory True) ["dhall", "dhall-haskell"]--getOrCreateCacheDirectory :: (MonadCatch m, Alternative m, MonadIO m) => Bool -> FilePath -> m FilePath-getOrCreateCacheDirectory showWarning cacheName = do+getOrCreateCacheDirectory+    :: (MonadCatch m, Alternative m, MonadState CacheWarning m, MonadIO m)+    => FilePath -> m FilePath+getOrCreateCacheDirectory cacheName = do     let warn message = do-            when showWarning (printWarning message)+            cacheWarningStatus <- State.get +            case cacheWarningStatus of+                CacheWarned    -> printWarning message+                CacheNotWarned -> return ()++            State.put CacheWarned+             empty      let handler action dir (ioex :: IOException) = do@@ -857,14 +922,19 @@                 then                     return ()                 else do+                    let render f = if f permissions then "✓" else "✗"                     let message =                              "The directory:\n"                           <> "\n"                           <> "↳ " <> dir <> "\n"                           <> "\n"                           <> "... does not give you permission to read, write, or search files.\n\n"+                          <> "\n"                           <> "The directory's current permissions are:\n"-                          <> show permissions <> "\n"+                          <> "\n"+                          <> "• " <> render Directory.readable <> " readable\n"+                          <> "• " <> render Directory.writable <> " writable\n"+                          <> "• " <> render Directory.searchable <> " searchable\n"                      warn message @@ -908,7 +978,7 @@                              setPermissions dir -    cacheBaseDirectory <- getCacheBaseDirectory showWarning+    cacheBaseDirectory <- getCacheBaseDirectory      let directory = cacheBaseDirectory </> cacheName @@ -926,8 +996,9 @@      return directory -getCacheBaseDirectory :: (Alternative m, MonadIO m) => Bool -> m FilePath-getCacheBaseDirectory showWarning = alternative₀ <|> alternative₁ <|> alternative₂+getCacheBaseDirectory+    :: (MonadState CacheWarning m, Alternative m, MonadIO m) => m FilePath+getCacheBaseDirectory = alternative₀ <|> alternative₁ <|> alternative₂   where     alternative₀ = do         maybeXDGCacheHome <-@@ -957,6 +1028,8 @@         where isWindows = System.Info.os == "mingw32"      alternative₂ = do+        cacheWarningStatus <- State.get+         let message =                 "\n"              <> "\ESC[1;33mWarning\ESC[0m: "@@ -965,68 +1038,156 @@              <> "You can provide a cache base directory by pointing the $XDG_CACHE_HOME\n"              <> "environment variable to a directory with read and write permissions.\n" -        when showWarning (liftIO (System.IO.hPutStrLn System.IO.stderr message))+        case cacheWarningStatus of+            CacheNotWarned ->+                liftIO (System.IO.hPutStrLn System.IO.stderr message)+            CacheWarned ->+                return () +        State.put CacheWarned+         empty  -- If the URL contains headers typecheck them and replace them with their normal -- forms.-normalizeHeaders :: URL -> StateT Status IO URL-normalizeHeaders url@URL { headers = Just headersExpression } = do+normalizeHeadersIn :: URL -> StateT Status IO URL+normalizeHeadersIn url@URL { headers = Just headersExpression } = do     Status { _stack } <- State.get     loadedExpr <- loadWith headersExpression+    let handler (e :: SomeException) = throwMissingImport (Imported _stack e)+    normalized <- liftIO $ handle handler (normalizeHeaders loadedExpr)+    return url { headers = Just (fmap absurd normalized) } -    let go key₀ key₁ = do-            let expected :: Expr Src Void-                expected =-                    App List-                        ( Record $ Core.makeRecordField <$>-                            Dhall.Map.fromList-                                [ (key₀, Text)-                                , (key₁, Text)-                                ]-                        )+normalizeHeadersIn url = return url -            let suffix_ = Dhall.Pretty.Internal.prettyToStrictText expected-            let annot = case loadedExpr of-                    Note (Src begin end bytes) _ ->-                        Note (Src begin end bytes') (Annot loadedExpr expected)-                      where-                        bytes' = bytes <> " : " <> suffix_-                    _ ->-                        Annot loadedExpr expected+-- | Empty origin headers used for remote contexts+--   (and fallback when nothing is set in env or config file)+emptyOriginHeaders :: Expr Src Import+emptyOriginHeaders = ListLit (Just (fmap absurd originHeadersTypeExpr)) mempty -            _ <- case (Dhall.TypeCheck.typeOf annot) of-                Left err -> throwMissingImport (Imported _stack err)-                Right _  -> return ()+-- | A fake Src to annotate headers expressions with.+--   We need to wrap headers expressions in a Note for nice error reporting,+--   and because ImportAlt handling only catches SourcedExceptions+headersSrc :: Src+headersSrc = Src {+        srcStart = SourcePos {+            sourceName = fakeSrcName,+            sourceLine = mkPos 1,+            sourceColumn = mkPos 1+        },+        srcEnd = SourcePos {+            sourceName = fakeSrcName,+            sourceLine = mkPos 1,+            sourceColumn = mkPos (Text.length fakeSrcText)+        },+        srcText = fakeSrcText+    }+  where+    fakeSrcText = "«Origin Header Configuration»"+    fakeSrcName = "[builtin]" -            return (Core.normalize loadedExpr)+-- | Load headers only from the environment (used in tests)+envOriginHeaders :: Expr Src Import+envOriginHeaders = Note headersSrc (Embed (Import (ImportHashed Nothing (Env "DHALL_HEADERS")) Code)) -    let handler₀ (e :: SomeException) = do-            {- Try to typecheck using the preferred @mapKey@/@mapValue@ fields-               and fall back to @header@/@value@ if that fails. However, if-               @header@/@value@ still fails then re-throw the original exception-               for @mapKey@ / @mapValue@. -}-            let handler₁ (_ :: SomeException) =-                    throwMissingImport (Imported _stack e)+-- | Load headers in env, falling back to config file+defaultOriginHeaders :: IO (Expr Src Import)+#ifndef WITH_HTTP+defaultOriginHeaders = return emptyOriginHeaders+#else+defaultOriginHeaders = do+    fromFile <- originHeadersFileExpr+    return (Note headersSrc (ImportAlt envOriginHeaders (Note headersSrc fromFile)))+#endif -            handle handler₁ (go "header" "value")+-- | Given a headers expression, return an origin headers loader+originHeadersLoader :: IO (Expr Src Import) -> StateT Status IO OriginHeaders+originHeadersLoader headersExpr = do -    headersExpression' <--        handle handler₀ (go "mapKey" "mapValue")+    -- Load the headers using the parent stack, which should always be a local+    -- import (we only load headers for the first remote import) -    return url { headers = Just (fmap absurd headersExpression') }+    status <- State.get -normalizeHeaders url = return url+    let parentStack = fromMaybe abortEmptyStack (nonEmpty (NonEmpty.tail (_stack status))) +    let headerLoadStatus = status { _stack = parentStack }++    (headers, _) <- liftIO (State.runStateT doLoad headerLoadStatus)++    -- return cached headers next time+    _ <- State.modify (\state -> state { _loadOriginHeaders = return headers })++    return headers+  where+    abortEmptyStack = Core.internalError "Origin headers loaded with an empty stack"++    doLoad = do+        partialExpr <- liftIO headersExpr+        loaded <- loadWith (Note headersSrc (ImportAlt partialExpr emptyOriginHeaders))+        liftIO (toOriginHeaders loaded)+ -- | Default starting `Status`, importing relative to the given directory. emptyStatus :: FilePath -> Status-emptyStatus = emptyStatusWithManager defaultNewManager+emptyStatus = makeEmptyStatus defaultNewManager defaultOriginHeaders +-- | See 'emptyStatus'+emptyStatusWithManager+    :: IO Manager+    -> FilePath+    -> Status+emptyStatusWithManager newManager = makeEmptyStatus newManager defaultOriginHeaders+ -- | See 'emptyStatus'.-emptyStatusWithManager :: IO Manager -> FilePath -> Status-emptyStatusWithManager newManager = emptyStatusWith newManager fetchRemote+makeEmptyStatus+    :: IO Manager+    -> IO (Expr Src Import)+    -> FilePath+    -> Status+makeEmptyStatus newManager headersExpr rootDirectory =+    emptyStatusWith newManager (originHeadersLoader headersExpr) fetchRemote fetchRemoteBytes rootImport+  where+    prefix = if FilePath.isRelative rootDirectory+      then Here+      else Absolute +    pathComponents =+        fmap Text.pack (reverse (FilePath.splitDirectories rootDirectory))++    directoryAsFile = File (Directory pathComponents) "."++    rootImport = Import+      { importHashed = ImportHashed+        { hash = Nothing+        , importType = Local prefix directoryAsFile+        }+      , importMode = Code+      }++{-| Default `Status` appropriate for a server interpreting Dhall code++    Using this `Status` ensures that interpreted Dhall code cannot access+    server-local resources (like files or environment variables)+-}+remoteStatus+    :: URL+    -- ^ Public address of the server+    -> Status+remoteStatus = remoteStatusWithManager defaultNewManager++-- | See `remoteStatus`+remoteStatusWithManager :: IO Manager -> URL -> Status+remoteStatusWithManager newManager url =+    emptyStatusWith newManager (originHeadersLoader (pure emptyOriginHeaders)) fetchRemote fetchRemoteBytes rootImport+  where+    rootImport = Import+      { importHashed = ImportHashed+        { hash = Nothing+        , importType = Remote url+        }+      , importMode = Code+      }+ {-| Generalized version of `load`      You can configure the desired behavior through the initial `Status` that you@@ -1072,11 +1233,29 @@    ImportAlt a b -> loadWith a `catch` handler₀     where-      handler₀ (SourcedException (Src begin _ text₀) (MissingImports es₀)) =-          loadWith b `catch` handler₁+      is :: forall e . Exception e => SomeException -> Bool+      is exception = Maybe.isJust (Exception.fromException @e exception)++      isNotResolutionError exception =+              is @(Imported (TypeError Src Void)) exception+          ||  is @(Imported  Cycle              ) exception+          ||  is @(Imported  HashMismatch       ) exception+          ||  is @(Imported  ParseError         ) exception++      handler₀ exception₀@(SourcedException (Src begin _ text₀) (MissingImports es₀))+          | any isNotResolutionError es₀ =+              throwM exception₀+          | otherwise = do+              loadWith b `catch` handler₁         where-          handler₁ (SourcedException (Src _ end text₁) (MissingImports es₁)) =-              throwM (SourcedException (Src begin end text₂) (MissingImports (es₀ ++ es₁)))+          handler₁ exception₁@(SourcedException (Src _ end text₁) (MissingImports es₁))+              | any isNotResolutionError es₁ =+                  throwM exception₁+              | otherwise =+                  -- Fix the source span for the error message to encompass both+                  -- alternatives, since both are equally to blame for the+                  -- failure if neither succeeds.+                  throwM (SourcedException (Src begin end text₂) (MissingImports (es₀ ++ es₁)))             where               text₂ = text₀ <> " ? " <> text₁ @@ -1087,7 +1266,7 @@   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+  Lam cs a b           -> Lam cs <$> functionBindingExprs loadWith a <*> loadWith b   Field a b            -> Field <$> loadWith a <*> pure b   expression           -> Syntax.unsafeSubExpressions loadWith expression @@ -1097,61 +1276,41 @@  -- | 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 =-                "\n"-            <> "\ESC[1;33mWarning\ESC[0m: "-            <> message--    liftIO $ System.IO.hPutStrLn System.IO.stderr warning+loadWithManager newManager =+    loadWithStatus+        (makeEmptyStatus newManager defaultOriginHeaders ".")+        UseSemanticCache  -- | Resolve all imports within an expression, importing relative to the given -- directory. loadRelativeTo :: FilePath -> SemanticCacheMode -> Expr Src Import -> IO (Expr Src Void)-loadRelativeTo = loadRelativeToWithManager defaultNewManager+loadRelativeTo parentDirectory = loadWithStatus+    (makeEmptyStatus defaultNewManager defaultOriginHeaders parentDirectory)  -- | See 'loadRelativeTo'.-loadRelativeToWithManager-    :: IO Manager-    -> FilePath+loadWithStatus+    :: Status     -> SemanticCacheMode     -> Expr Src Import     -> IO (Expr Src Void)-loadRelativeToWithManager newManager rootDirectory semanticCacheMode expression =+loadWithStatus status semanticCacheMode expression =     State.evalStateT         (loadWith expression)-        (emptyStatusWithManager newManager rootDirectory) { _semanticCacheMode = semanticCacheMode }+        status { _semanticCacheMode = semanticCacheMode } -encodeExpression-    :: StandardVersion-    -- ^ `NoVersion` means to encode without the version tag-    -> Expr Void Void-    -> Data.ByteString.ByteString-encodeExpression _standardVersion expression = bytesStrict+encodeExpression :: Expr Void Void -> Data.ByteString.ByteString+encodeExpression expression = bytesStrict   where     intermediateExpression :: Expr Void Import     intermediateExpression = fmap absurd expression -    encoding =-        case _standardVersion of-            NoVersion ->-                Codec.Serialise.encode intermediateExpression-            s ->-                    Encoding.encodeListLen 2-                <>  Encoding.encodeString v-                <>  Codec.Serialise.encode intermediateExpression-              where-                v = Dhall.Binary.renderStandardVersion s+    encoding = Codec.Serialise.encode intermediateExpression      bytesStrict = Write.toStrictByteString encoding  -- | Hash a fully resolved expression hashExpression :: Expr Void Void -> Dhall.Crypto.SHA256Digest-hashExpression expression =-    Dhall.Crypto.sha256Hash (encodeExpression NoVersion expression)+hashExpression = Dhall.Crypto.sha256Hash . encodeExpression  {-| Convenience utility to hash a fully resolved expression and return the     base-16 encoded hash with the @sha256:@ prefix@@ -1173,6 +1332,7 @@ assertNoImports :: MonadIO io => Expr Src Import -> io (Expr Src Void) assertNoImports expression =     Core.throws (traverse (\_ -> Left ImportResolutionDisabled) expression)+{-# INLINABLE assertNoImports #-}  {-| This function is used by the @--transitive@ option of the     @dhall {freeze,format,lint}@ subcommands to determine which dependencies@@ -1205,6 +1365,9 @@     -- types are not interpreted and therefore don't need to be modified     case importMode child of         RawText ->+            ignore++        RawBytes ->             ignore          Location ->
+ src/Dhall/Import/Headers.hs view
@@ -0,0 +1,129 @@+{-# LANGUAGE CPP                 #-}+{-# LANGUAGE OverloadedStrings   #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE ViewPatterns        #-}++module Dhall.Import.Headers+    ( normalizeHeaders+    , originHeadersTypeExpr+    , toHeaders+    , toOriginHeaders+    ) where++import Control.Applicative (Alternative (..), liftA2)+import Control.Exception   (SomeException)+import Control.Monad.Catch (handle, throwM)+import Data.Text           (Text)+import Data.Void           (Void)+import Dhall.Core          (Chunks (..), Expr (..))+import Dhall.Import.Types  (HTTPHeader, OriginHeaders)+import Dhall.Parser        (Src (..))++import qualified Data.CaseInsensitive+import qualified Data.Foldable+import qualified Data.HashMap.Strict   as HashMap+import qualified Data.Text.Encoding+import qualified Dhall.Core            as Core+import qualified Dhall.Map+import qualified Dhall.Pretty.Internal+import qualified Dhall.TypeCheck++-- | Given a well-typed (of type `List { header : Text, value Text }` or+-- `List { mapKey : Text, mapValue Text }`) headers expressions in normal form+-- construct the corresponding binary http headers; otherwise return the empty+-- list.+toHeaders :: Expr s a -> [HTTPHeader]+toHeaders (ListLit _ hs) = Data.Foldable.toList (Data.Foldable.fold maybeHeaders)+  where+      maybeHeaders = mapM toHeader hs+toHeaders _ = []++toHeader :: Expr s a -> Maybe HTTPHeader+toHeader (RecordLit m) = do+    (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+    return (Data.CaseInsensitive.mk keyBytes, valueBytes)+      where+        lookupHeader = liftA2 (,) (Dhall.Map.lookup "header" m) (Dhall.Map.lookup "value" m)+        lookupMapKey = liftA2 (,) (Dhall.Map.lookup "mapKey" m) (Dhall.Map.lookup "mapValue" m)+toHeader _ =+    empty++-- | Normalize, typecheck and return OriginHeaders from a given expression.+toOriginHeaders :: Expr Src Void -> IO OriginHeaders+toOriginHeaders expr = fmap convert (normalizeOriginHeaders expr)+  where+    convert :: Expr s a -> OriginHeaders+    convert (ListLit _ hs) = HashMap.fromList (originPairs hs)+    convert _ = mempty++    originPairs hs = Data.Foldable.toList (Data.Foldable.fold (mapM toOriginPair hs))++    toOriginPair :: Expr s a -> Maybe (Text, [HTTPHeader])+    toOriginPair (RecordLit m) = do+      (Core.recordFieldValue -> TextLit (Chunks [] keyText), Core.recordFieldValue -> value)+          <- lookupMapKey+      return (keyText, toHeaders value)+        where+          lookupMapKey = liftA2 (,) (Dhall.Map.lookup "mapKey" m) (Dhall.Map.lookup "mapValue" m)+    toOriginPair _ = Nothing++makeHeadersTypeExpr :: Text -> Text -> Expr Src Void+makeHeadersTypeExpr keyKey valueKey =+  App List+      ( Record $ Core.makeRecordField <$>+          Dhall.Map.fromList+              [ (keyKey, Text)+              , (valueKey, Text)+              ]+      )++headersTypeExpr :: Expr Src Void+headersTypeExpr = makeHeadersTypeExpr "mapKey" "mapValue"++leagacyHeadersTypeExpr :: Expr Src Void+leagacyHeadersTypeExpr = makeHeadersTypeExpr "header" "value"++originHeadersTypeExpr :: Expr Src Void+originHeadersTypeExpr =+  App List+      ( Record $ Core.makeRecordField <$>+          Dhall.Map.fromList+              [ ("mapKey", Text)+              , ("mapValue", headersTypeExpr)+              ]+      )++typecheck :: Expr Src Void -> Expr Src Void -> IO (Expr Src Void)+typecheck expected expr = do+    let suffix_ = Dhall.Pretty.Internal.prettyToStrictText expected+    let annot = case expr of+            Note (Src begin end bytes) _ ->+                Note (Src begin end bytes') (Annot expr expected)+              where+                bytes' = bytes <> " : " <> suffix_+            _ ->+                Annot expr expected++    _ <- case (Dhall.TypeCheck.typeOf annot) of+        Left err -> throwM err+        Right _  -> return ()++    return (Core.normalize expr)++normalizeHeaders :: Expr Src Void -> IO (Expr Src Void)+normalizeHeaders headersExpr = do+    let handler₀ (e :: SomeException) = do+            {- Try to typecheck using the preferred @mapKey@/@mapValue@ fields+               and fall back to @header@/@value@ if that fails. However, if+               @header@/@value@ still fails then re-throw the original exception+               for @mapKey@ / @mapValue@. -}+            let handler₁ (_ :: SomeException) = throwM e+            handle handler₁ (typecheck leagacyHeadersTypeExpr headersExpr)++    handle handler₀ (typecheck headersTypeExpr headersExpr)++normalizeOriginHeaders :: Expr Src Void -> IO (Expr Src Void)+normalizeOriginHeaders = typecheck originHeadersTypeExpr
src/Dhall/Import/Types.hs view
@@ -8,27 +8,23 @@  import Control.Exception                (Exception) import Control.Monad.Trans.State.Strict (StateT)+import Data.ByteString                  (ByteString)+import Data.CaseInsensitive             (CI) import Data.Dynamic+import Data.HashMap.Strict              (HashMap) import Data.List.NonEmpty               (NonEmpty)-import Data.Text.Prettyprint.Doc        (Pretty (..)) import Data.Void                        (Void) import Dhall.Context                    (Context) import Dhall.Core-    ( Directory (..)-    , Expr-    , File (..)-    , FilePrefix (..)+    ( Expr     , Import (..)-    , ImportHashed (..)-    , ImportMode (..)-    , ImportType (..)     , ReifiedNormalizer (..)     , URL     ) import Dhall.Map                        (Map) import Dhall.Parser                     (Src)-import Lens.Family                      (LensLike')-import System.FilePath                  (isRelative, splitDirectories)+import Lens.Micro                       (Lens', lens)+import Prettyprinter                    (Pretty (..))  #ifdef WITH_HTTP import qualified Dhall.Import.Manager@@ -54,7 +50,7 @@     pretty (Chained import_) = pretty import_  -- | An import that has been fully interpeted-data ImportSemantics = ImportSemantics+newtype ImportSemantics = ImportSemantics     { importSemantics :: Expr Void Void     -- ^ The fully resolved import, typechecked and beta-normal.     }@@ -84,7 +80,17 @@   pure () #endif +-- | HTTP headers+type HTTPHeader = (CI ByteString, ByteString) +-- | A map of site origin -> HTTP headers+type OriginHeaders = HashMap Data.Text.Text [HTTPHeader]++{-| Used internally to track whether or not we've already warned the user about+    caching issues+-}+data CacheWarning = CacheNotWarned | CacheWarned+ -- | State threaded throughout the import process data Status = Status     { _stack :: NonEmpty Chained@@ -104,9 +110,16 @@     -- ^ Used to cache the `Dhall.Import.Manager.Manager` when making multiple     -- requests +    , _loadOriginHeaders :: StateT Status IO OriginHeaders+    -- ^ Load the origin headers from environment or configuration file.+    --   After loading once, further evaluations return the cached version.+     , _remote :: URL -> StateT Status IO Data.Text.Text     -- ^ The remote resolver, fetches the content at the given URL. +    , _remoteBytes :: URL -> StateT Status IO Data.ByteString.ByteString+    -- ^ Like `_remote`, except for `Dhall.Syntax.Expr.Bytes`+     , _substitutions :: Dhall.Substitution.Substitutions Src Void      , _normalizer :: Maybe (ReifiedNormalizer Void)@@ -114,12 +127,23 @@     , _startingContext :: Context (Expr Src Void)      , _semanticCacheMode :: SemanticCacheMode++    , _cacheWarning :: CacheWarning+    -- ^ Records whether or not we already warned the user about issues with+    --   cache directory     } --- | 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 {..}+-- | Initial `Status`, parameterised over the HTTP 'Manager',+--   the origin headers and the remote resolver,+--   importing relative to the given root import.+emptyStatusWith+    :: IO Manager+    -> StateT Status IO OriginHeaders+    -> (URL -> StateT Status IO Data.Text.Text)+    -> (URL -> StateT Status IO Data.ByteString.ByteString)+    -> Import+    -> Status+emptyStatusWith _newManager _loadOriginHeaders _remote _remoteBytes rootImport = Status {..}   where     _stack = pure (Chained rootImport) @@ -137,53 +161,43 @@      _semanticCacheMode = UseSemanticCache -    prefix = if isRelative rootDirectory-      then Here-      else Absolute-    pathComponents =-        fmap Data.Text.pack (reverse (splitDirectories rootDirectory))--    dirAsFile = File (Directory pathComponents) "."--    -- Fake import to set the directory we're relative to.-    rootImport = Import-      { importHashed = ImportHashed-        { hash = Nothing-        , importType = Local prefix dirAsFile-        }-      , importMode = Code-      }+    _cacheWarning = CacheNotWarned  -- | Lens from a `Status` to its `_stack` field-stack :: Functor f => LensLike' f Status (NonEmpty Chained)-stack k s = fmap (\x -> s { _stack = x }) (k (_stack s))+stack :: Lens' Status (NonEmpty Chained)+stack = lens _stack (\s x -> s { _stack = x })  -- | Lens from a `Status` to its `_graph` field-graph :: Functor f => LensLike' f Status [Depends]-graph k s = fmap (\x -> s { _graph = x }) (k (_graph s))+graph :: Lens' Status [Depends]+graph = lens _graph (\s x -> s { _graph = x })  -- | Lens from a `Status` to its `_cache` field-cache :: Functor f => LensLike' f Status (Map Chained ImportSemantics)-cache k s = fmap (\x -> s { _cache = x }) (k (_cache s))+cache :: Lens' Status (Map Chained ImportSemantics)+cache = lens _cache (\s x -> s { _cache = x })  -- | Lens from a `Status` to its `_remote` field-remote-    :: Functor f => LensLike' f Status (URL -> StateT Status IO Data.Text.Text)-remote k s = fmap (\x -> s { _remote = x }) (k (_remote s))+remote :: Lens' Status (URL -> StateT Status IO Data.Text.Text)+remote = lens _remote (\s x -> s { _remote = x }) +-- | Lens from a `Status` to its `_remote` field+remoteBytes :: Lens' Status (URL -> StateT Status IO Data.ByteString.ByteString)+remoteBytes = lens _remoteBytes (\s x -> s { _remoteBytes = x })+ -- | Lens from a `Status` to its `_substitutions` field-substitutions :: Functor f => LensLike' f Status (Dhall.Substitution.Substitutions Src Void)-substitutions k s =-    fmap (\x -> s { _substitutions = x }) (k (_substitutions s))+substitutions :: Lens' Status (Dhall.Substitution.Substitutions Src Void)+substitutions = lens _substitutions (\s x -> s { _substitutions = x })  -- | Lens from a `Status` to its `_normalizer` field-normalizer :: Functor f => LensLike' f Status (Maybe (ReifiedNormalizer Void))-normalizer k s = fmap (\x -> s {_normalizer = x}) (k (_normalizer s))+normalizer :: Lens' Status (Maybe (ReifiedNormalizer Void))+normalizer = lens _normalizer (\s x -> s {_normalizer = x})  -- | Lens from a `Status` to its `_startingContext` field-startingContext :: Functor f => LensLike' f Status (Context (Expr Src Void))-startingContext k s =-    fmap (\x -> s { _startingContext = x }) (k (_startingContext s))+startingContext :: Lens' Status (Context (Expr Src Void))+startingContext = lens _startingContext (\s x -> s { _startingContext = x })++-- | Lens from a `Status` to its `_cacheWarning` field+cacheWarning :: Lens' Status CacheWarning+cacheWarning = lens _cacheWarning (\s x -> s { _cacheWarning = x })  {-| This exception indicates that there was an internal error in Dhall's     import-related logic
src/Dhall/Lint.hs view
@@ -39,9 +39,8 @@ import qualified Data.List.NonEmpty as NonEmpty import qualified Data.Text          as Text import qualified Dhall.Core         as Core-import qualified Dhall.Map          as Map-import qualified Dhall.Optics-import qualified Lens.Family+import qualified Dhall.Map+import qualified Lens.Micro         as Lens  {-| Automatically improve a Dhall expression @@ -52,8 +51,8 @@     * consolidates nested @let@ bindings to use a multiple-@let@ binding with 'removeLetInLet'     * fixes paths of the form @.\/..\/foo@ to @..\/foo@ -}-lint :: Expr s Import -> Expr s Import-lint =  Dhall.Optics.rewriteOf subExpressions rewrite+lint :: Eq s => Expr s Import -> Expr s Import+lint =  Lens.rewriteOf subExpressions rewrite   where     rewrite e =             fixAssert                e@@ -144,7 +143,7 @@  isOrContainsAssert :: Expr s a -> Bool isOrContainsAssert (Assert _) = True-isOrContainsAssert e = Lens.Family.anyOf subExpressions isOrContainsAssert e+isOrContainsAssert e = Lens.anyOf subExpressions isOrContainsAssert e  -- | The difference between --@@ -176,7 +175,7 @@             (Core.shallowDenote -> App                 (Core.shallowDenote -> List)                 (Core.shallowDenote -> Record-                    (Map.sort ->+                    (Dhall.Map.sort ->                         [ ("mapKey", Core.shallowDenote . Core.recordFieldValue -> Text)                         , ("mapValue", _)                         ]@@ -192,14 +191,14 @@     , Just keyValues' <- traverse convert keyValues =         Just             (ToMap-                (RecordLit (Map.fromList (Foldable.toList keyValues')))+                (RecordLit (Dhall.Map.fromList (Foldable.toList keyValues')))                 Nothing             )   where     convert keyValue =         case Core.shallowDenote keyValue of             RecordLit-                (Map.sort ->+                (Dhall.Map.sort ->                     [ ("mapKey"  , Core.shallowDenote . Core.recordFieldValue -> TextLit (Chunks [] key))                     , ("mapValue", value)                     ]
src/Dhall/Main.hs view
@@ -21,34 +21,39 @@     , main     ) where -import Control.Applicative       (optional, (<|>))-import Control.Exception         (Handler (..), SomeException)-import Control.Monad             (when)-import Data.Foldable             (for_)-import Data.List.NonEmpty        (NonEmpty (..))-import Data.Text                 (Text)-import Data.Text.Prettyprint.Doc (Doc, Pretty)-import Data.Void                 (Void)-import Dhall.Freeze              (Intent (..), Scope (..))+import Control.Applicative (optional, (<|>))+import Control.Exception   (Handler (..), SomeException)+import Control.Monad       (when)+import Data.Foldable       (for_)+import Data.List.NonEmpty  (NonEmpty (..), nonEmpty)+import Data.Maybe          (fromMaybe)+import Data.Monoid         (Endo (..))+import Data.Text           (Text)+import Data.Void           (Void)+import Dhall.Freeze        (Intent (..), Scope (..)) import Dhall.Import     ( Depends (..)     , Imported (..)     , SemanticCacheMode (..)     , _semanticCacheMode     )-import Dhall.Parser              (Src)-import Dhall.Pretty              (Ann, CharacterSet (..), annToAnsiStyle)-import Dhall.Schemas             (Schemas (..))-import Dhall.TypeCheck-    ( Censored (..)-    , DetailedTypeError (..)-    , TypeError+import Dhall.Package       (PackagingMode (..), writePackage)+import Dhall.Parser        (Src)+import Dhall.Pretty+    ( Ann+    , CharacterSet (..)+    , annToAnsiStyle+    , detectCharacterSet     )-import Dhall.Version             (dhallVersionString)-import Options.Applicative       (Parser, ParserInfo)-import System.Exit               (ExitCode, exitFailure)-import System.IO                 (Handle)-import Text.Dot                  ((.->.))+import Dhall.Schemas       (Schemas (..))+import Dhall.TypeCheck     (Censored (..), DetailedTypeError (..), TypeError)+import Dhall.Version       (dhallVersionString)+import Lens.Micro          (set)+import Options.Applicative (Parser, ParserInfo)+import Prettyprinter       (Doc, Pretty)+import System.Exit         (ExitCode, exitFailure)+import System.IO           (Handle)+import Text.Dot            ((.->.))  import Dhall.Core     ( Expr (Annot)@@ -65,15 +70,15 @@     , Input (..)     , Output (..)     , OutputMode (..)-    , PossiblyTransitiveInput (..)     , Transitivity (..)+    , handleMultipleChecksFailed     )  import qualified Codec.CBOR.JSON import qualified Codec.CBOR.Read import qualified Codec.CBOR.Write import qualified Control.Exception-import qualified Control.Monad.Trans.State.Strict          as State+import qualified Control.Monad.Trans.State.Strict   as State import qualified Data.Aeson import qualified Data.Aeson.Encode.Pretty import qualified Data.ByteString.Lazy@@ -81,20 +86,18 @@ import qualified Data.Map import qualified Data.Text import qualified Data.Text.IO-import qualified Data.Text.Prettyprint.Doc                 as Pretty-import qualified Data.Text.Prettyprint.Doc.Render.Terminal as Pretty-import qualified Data.Text.Prettyprint.Doc.Render.Text     as Pretty.Text import qualified Dhall import qualified Dhall.Binary import qualified Dhall.Core import qualified Dhall.Diff-import qualified Dhall.DirectoryTree                       as DirectoryTree+import qualified Dhall.DirectoryTree                as DirectoryTree import qualified Dhall.Format import qualified Dhall.Freeze import qualified Dhall.Import import qualified Dhall.Import.Types import qualified Dhall.Lint import qualified Dhall.Map+import qualified Dhall.Package import qualified Dhall.Pretty import qualified Dhall.Repl import qualified Dhall.Schemas@@ -103,9 +106,12 @@ import qualified Dhall.Util import qualified GHC.IO.Encoding import qualified Options.Applicative-import qualified System.AtomicWrite.Writer.LazyText        as AtomicWrite.LazyText+import qualified Prettyprinter                      as Pretty+import qualified Prettyprinter.Render.Terminal      as Pretty+import qualified Prettyprinter.Render.Text          as Pretty.Text+import qualified System.AtomicWrite.Writer.LazyText as AtomicWrite.LazyText import qualified System.Console.ANSI-import qualified System.Exit                               as Exit+import qualified System.Exit                        as Exit import qualified System.FilePath import qualified System.IO import qualified Text.Dot@@ -113,19 +119,13 @@  -- | Top-level program options data Options = Options-    { mode    :: Mode-    , explain :: Bool-    , plain   :: Bool-    , ascii   :: Bool-    , censor  :: Censor+    { mode               :: Mode+    , explain            :: Bool+    , plain              :: Bool+    , chosenCharacterSet :: Maybe CharacterSet+    , censor             :: Censor     } -ignoreSemanticCache :: Mode -> Bool-ignoreSemanticCache Default {..} = semanticCacheMode == IgnoreSemanticCache-ignoreSemanticCache Resolve {..} = semanticCacheMode == IgnoreSemanticCache-ignoreSemanticCache Type {..}    = semanticCacheMode == IgnoreSemanticCache-ignoreSemanticCache _            = False- -- | The subcommands for the @dhall@ executable data Mode     = Default@@ -149,11 +149,11 @@           }     | Normalize { file :: Input , alpha :: Bool }     | Repl-    | Format { possiblyTransitiveInput :: PossiblyTransitiveInput, outputMode :: OutputMode }-    | Freeze { possiblyTransitiveInput :: PossiblyTransitiveInput, all_ :: Bool, cache :: Bool, outputMode :: OutputMode }-    | Hash { file :: Input }+    | Format { deprecatedInPlace :: Bool, transitivity :: Transitivity, outputMode :: OutputMode, inputs :: NonEmpty Input }+    | Freeze { deprecatedInPlace :: Bool, transitivity :: Transitivity, all_ :: Bool, cache :: Bool, outputMode :: OutputMode, inputs :: NonEmpty Input }+    | Hash { file :: Input, cache :: Bool }     | Diff { expr1 :: Text, expr2 :: Text }-    | Lint { possiblyTransitiveInput :: PossiblyTransitiveInput, outputMode :: OutputMode }+    | Lint { deprecatedInPlace :: Bool, transitivity :: Transitivity, outputMode :: OutputMode, inputs :: NonEmpty Input }     | Tags           { input :: Input           , output :: Output@@ -163,9 +163,13 @@     | Encode { file :: Input, json :: Bool }     | Decode { file :: Input, json :: Bool, quiet :: Bool }     | Text { file :: Input, output :: Output }-    | DirectoryTree { file :: Input, path :: FilePath }+    | DirectoryTree { allowSeparators :: Bool, file :: Input, path :: FilePath }     | Schemas { file :: Input, outputMode :: OutputMode, schemas :: Text }     | SyntaxTree { file :: Input, noted :: Bool }+    | Package+        { packageOptions :: Endo Dhall.Package.Options+        , packageFiles :: NonEmpty FilePath+        }  -- | This specifies how to resolve transitive dependencies data ResolveMode@@ -201,7 +205,7 @@     <$> parseMode     <*> switch "explain" "Explain error messages in more detail"     <*> switch "plain" "Disable syntax highlighting"-    <*> switch "ascii" "Format code using only ASCII syntax"+    <*> parseCharacterSet     <*> parseCensor   where     switch name description =@@ -215,6 +219,19 @@         f True  = Censor         f False = NoCensor +    parseCharacterSet =+            Options.Applicative.flag'+                (Just Unicode)+                (   Options.Applicative.long "unicode"+                <>  Options.Applicative.help "Format code using only Unicode syntax"+                )+        <|> Options.Applicative.flag'+                (Just ASCII)+                (   Options.Applicative.long "ascii"+                <>  Options.Applicative.help "Format code using only ASCII syntax"+                )+        <|> pure Nothing+ subcommand :: Group -> String -> String -> Parser a -> Parser a subcommand group name description parser =     Options.Applicative.hsubparser@@ -235,17 +252,17 @@             Manipulate             "format"             "Standard code formatter for the Dhall language"-            (Format <$> parseInplaceTransitive <*> parseCheck "formatted")+            (Format <$> deprecatedInPlace <*> parseTransitiveSwitch <*> parseCheck "formatted" <*> parseFiles)     <|> subcommand             Manipulate             "freeze"             "Add integrity checks to remote import statements of an expression"-            (Freeze <$> parseInplaceTransitive <*> parseAllFlag <*> parseCacheFlag <*> parseCheck "frozen")+            (Freeze <$> deprecatedInPlace <*> parseTransitiveSwitch <*> parseAllFlag <*> parseCacheFlag <*> parseCheck "frozen" <*> parseFiles)     <|> subcommand             Manipulate             "lint"             "Improve Dhall code by using newer language features and removing dead code"-            (Lint <$> parseInplaceTransitive <*> parseCheck "linted")+            (Lint <$> deprecatedInPlace <*> parseTransitiveSwitch <*> parseCheck "linted" <*> parseFiles)     <|> subcommand             Manipulate             "rewrite-with-schemas"@@ -260,7 +277,7 @@             Generate             "to-directory-tree"             "Convert nested records of Text literals into a directory tree"-            (DirectoryTree <$> parseFile <*> parseDirectoryTreeOutput)+            (DirectoryTree <$> parseDirectoryTreeAllowSeparators <*> parseFile <*> parseDirectoryTreeOutput)     <|> subcommand             Interpret             "resolve"@@ -300,9 +317,14 @@             Miscellaneous             "hash"             "Compute semantic hashes for Dhall expressions"-            (Hash <$> parseFile)+            (Hash <$> parseFile <*> parseCache)     <|> subcommand             Miscellaneous+            "package"+            "Create a package.dhall referencing the provided paths"+            (Package <$> parsePackageOptions <*> parsePackageFiles)+    <|> subcommand+            Miscellaneous             "tags"             "Generate etags file"             (Tags <$> parseInput <*> parseTagsOutput <*> parseSuffixes <*> parseFollowSymlinks)@@ -325,6 +347,12 @@         <*> parseVersion         )   where+    deprecatedInPlace =+        Options.Applicative.switch+            (   Options.Applicative.long "inplace"+            <>  Options.Applicative.internal -- completely hidden from help+            )+     argument =             fmap Data.Text.pack         .   Options.Applicative.strArgument@@ -342,6 +370,21 @@                 <>  Options.Applicative.action "file"                 ) +    parseFiles = fmap f (Options.Applicative.many p)+      where+        -- Parse explicit stdin in the input filepaths+        parseStdin inputs+            | InputFile "-" `elem` inputs = StandardInput : filter (/= InputFile "-") inputs+            | otherwise = inputs++        f = fromMaybe (pure StandardInput) . nonEmpty . parseStdin . fmap InputFile++        p = Options.Applicative.strArgument+                (   Options.Applicative.help "Read expression from files instead of standard input"+                <>  Options.Applicative.metavar "FILES"+                <>  Options.Applicative.action "file"+                )+     parseOutput = fmap f (optional p)       where         f Nothing = StandardOutput@@ -415,22 +458,15 @@             <>  Options.Applicative.action "file"             ) +    parseTransitiveSwitch = Options.Applicative.flag NonTransitive Transitive+        (   Options.Applicative.long "transitive"+        <>  Options.Applicative.help "Modify the input and its transitive relative imports in-place"+        )+     parseInplaceNonTransitive =             fmap InputFile parseInplace         <|> pure StandardInput -    parseInplaceTransitive =-            fmap (\f -> PossiblyTransitiveInputFile f NonTransitive) parseInplace-        <|> fmap (\f -> PossiblyTransitiveInputFile f    Transitive) parseTransitive-        <|> pure NonTransitiveStandardInput-      where-        parseTransitive = Options.Applicative.strOption-            (   Options.Applicative.long "transitive"-            <>  Options.Applicative.help "Modify the specified file and its transitive relative imports in-place"-            <>  Options.Applicative.metavar "FILE"-            <>  Options.Applicative.action "file"-            )-     parseInput = fmap f (optional p)       where         f  Nothing    = StandardInput@@ -483,7 +519,7 @@     parseAllFlag =         Options.Applicative.switch         (   Options.Applicative.long "all"-        <>  Options.Applicative.help "Add integrity checks to all imports (not just remote imports)"+        <>  Options.Applicative.help "Add integrity checks to all imports (not just remote imports) except for missing imports"         )      parseCacheFlag =@@ -510,6 +546,12 @@             <>  Options.Applicative.metavar "EXPR"             ) +    parseDirectoryTreeAllowSeparators =+        Options.Applicative.switch+            (   Options.Applicative.long "allow-path-separators"+            <>  Options.Applicative.help "Whether to allow path separators in file names"+            )+     parseDirectoryTreeOutput =         Options.Applicative.strOption             (   Options.Applicative.long "output"@@ -524,6 +566,39 @@             <>  Options.Applicative.help "Print `Note` constructors"             ) +    parseCache =+        Options.Applicative.switch+            (   Options.Applicative.long "cache"+            <>  Options.Applicative.help "Cache the hashed expression"+            )++    parsePackageOptions :: Parser (Endo Dhall.Package.Options)+    parsePackageOptions = do+        packageMode <- (optional . Options.Applicative.flag' RecursiveSubpackages)+            ( Options.Applicative.short 'r'+            <> Options.Applicative.long "recursive"+            <> Options.Applicative.help "Create packages for all subdirectories first."+            )++        packageFileName <- (optional . Options.Applicative.strOption)+                (   Options.Applicative.long "name"+                <>  Options.Applicative.help "The filename of the package"+                <>  Options.Applicative.metavar "NAME"+                <>  Options.Applicative.action "file"+                )++        pure $+            maybe mempty (Endo . set Dhall.Package.packagingMode) packageMode <>+            maybe mempty (Endo . set Dhall.Package.packageFileName) packageFileName++    parsePackageFiles = (:|) <$> p <*> Options.Applicative.many p+      where+        p = Options.Applicative.strArgument+                (   Options.Applicative.help "Paths that may either point to files or directories. If the latter is the case all *.dhall files in the directory will be included."+                <>  Options.Applicative.metavar "PATH"+                <>  Options.Applicative.action "file"+                )+ -- | `ParserInfo` for the `Options` type parserInfoOptions :: ParserInfo Options parserInfoOptions =@@ -543,10 +618,6 @@ -- | Run the command specified by the `Options` type command :: Options -> IO () command (Options {..}) = do-    let characterSet = case ascii of-            True  -> ASCII-            False -> Unicode-     GHC.IO.Encoding.setLocaleEncoding System.IO.utf8      let rootDirectory = \case@@ -557,6 +628,16 @@      let getExpression = Dhall.Util.getExpression censor +    -- The characterSet detection used here only works on the source+    -- expression, before any transformation is applied. This helper is there+    -- make sure the detection is done on the correct expr.+    let getExpressionAndCharacterSet file = do+            expr <- getExpression file++            let characterSet = fromMaybe (detectCharacterSet expr) chosenCharacterSet++            return (expr, characterSet)+     let handle io =             Control.Exception.catches io                 [ Handler handleTypeError@@ -613,8 +694,8 @@             Pretty.renderIO h ansiStream             Data.Text.IO.hPutStrLn h "" -    let render :: Pretty a => Handle -> Expr Src a -> IO ()-        render h expression = do+    let render :: Pretty a => Handle -> CharacterSet -> Expr Src a -> IO ()+        render h characterSet expression = do             let doc = Dhall.Pretty.prettyCharacterSet characterSet expression              renderDoc h doc@@ -625,8 +706,6 @@              AtomicWrite.LazyText.atomicWriteFile file (Pretty.Text.renderLazy stream) -    when (not $ ignoreSemanticCache mode) Dhall.Import.warnAboutMissingCaches-     handle $ case mode of         Version ->             putStrLn dhallVersionString@@ -638,7 +717,7 @@                     Exit.exitSuccess                 else return () -            expression <- getExpression file+            (expression, characterSet) <- getExpressionAndCharacterSet file              resolvedExpression <-                 Dhall.Import.loadRelativeTo (rootDirectory file) semanticCacheMode expression@@ -658,7 +737,7 @@                         else alphaNormalizedExpression              case output of-                StandardOutput -> render System.IO.stdout annotatedExpression+                StandardOutput -> render System.IO.stdout characterSet annotatedExpression                  OutputFile file_ ->                     writeDocToFile@@ -717,15 +796,15 @@                  $   _cache          Resolve { resolveMode = Nothing, ..} -> do-            expression <- getExpression file+            (expression, characterSet) <- getExpressionAndCharacterSet file              resolvedExpression <-                 Dhall.Import.loadRelativeTo (rootDirectory file) semanticCacheMode expression -            render System.IO.stdout resolvedExpression+            render System.IO.stdout characterSet resolvedExpression          Normalize {..} -> do-            expression <- getExpression file+            (expression, characterSet) <- getExpressionAndCharacterSet file              resolvedExpression <- Dhall.Import.assertNoImports expression @@ -738,10 +817,10 @@                     then Dhall.Core.alphaNormalize normalizedExpression                     else normalizedExpression -            render System.IO.stdout alphaNormalizedExpression+            render System.IO.stdout characterSet alphaNormalizedExpression          Type {..} -> do-            expression <- getExpression file+            (expression, characterSet) <- getExpressionAndCharacterSet file              resolvedExpression <-                 Dhall.Import.loadRelativeTo (rootDirectory file) semanticCacheMode expression@@ -750,10 +829,12 @@              if quiet                 then return ()-                else render System.IO.stdout inferredType+                else render System.IO.stdout characterSet inferredType          Repl ->-            Dhall.Repl.repl characterSet explain+            Dhall.Repl.repl+                (fromMaybe Unicode chosenCharacterSet) -- Default to Unicode if no characterSet specified+                explain          Diff {..} -> do             expression1 <- Dhall.inputExpr expr1@@ -768,16 +849,21 @@                 then return ()                 else Exit.exitFailure -        Format {..} ->-            Dhall.Format.format-                Dhall.Format.Format{ input = possiblyTransitiveInput, ..}+        Format {..} -> do+            when deprecatedInPlace $+                System.IO.hPutStrLn System.IO.stderr "Warning: the flag \"--inplace\" is deprecated" +            Dhall.Format.format Dhall.Format.Format{..}+         Freeze {..} -> do+            when deprecatedInPlace $+                System.IO.hPutStrLn System.IO.stderr "Warning: the flag \"--inplace\" is deprecated"+             let scope = if all_ then AllImports else OnlyRemoteImports              let intent = if cache then Cache else Secure -            Dhall.Freeze.freeze outputMode possiblyTransitiveInput scope intent characterSet censor+            Dhall.Freeze.freeze outputMode transitivity inputs scope intent chosenCharacterSet censor          Hash {..} -> do             expression <- getExpression file@@ -790,37 +876,47 @@             let normalizedExpression =                     Dhall.Core.alphaNormalize (Dhall.Core.normalize resolvedExpression) +            if cache+                then Dhall.Import.writeExpressionToSemanticCache normalizedExpression+                else return ()+             Data.Text.IO.putStrLn (Dhall.Import.hashExpressionToCode normalizedExpression) -        Lint { possiblyTransitiveInput = input0, ..} -> go input0+        Lint { transitivity = transitivity0, ..} -> do+            when deprecatedInPlace $+                System.IO.hPutStrLn System.IO.stderr "Warning: the flag \"--inplace\" is deprecated"++            handleMultipleChecksFailed "lint" "linted" go inputs           where             go input = do                 let directory = case input of-                        NonTransitiveStandardInput         -> "."-                        PossiblyTransitiveInputFile file _ -> System.FilePath.takeDirectory file+                        StandardInput  -> "."+                        InputFile file -> System.FilePath.takeDirectory file                  let status = Dhall.Import.emptyStatus directory -                (originalText, transitivity) <- case input of-                    PossiblyTransitiveInputFile file transitivity -> do+                (inputName, originalText, transitivity) <- case input of+                    InputFile file -> do                         text <- Data.Text.IO.readFile file -                        return (text, transitivity)-                    NonTransitiveStandardInput -> do+                        return (file, text, transitivity0)+                    StandardInput -> do                         text <- Data.Text.IO.getContents -                        return (text, NonTransitive)+                        return ("(input)", text, NonTransitive)                  (Header header, parsedExpression) <--                    Dhall.Util.getExpressionAndHeaderFromStdinText censor originalText+                    Dhall.Util.getExpressionAndHeaderFromStdinText censor inputName originalText +                let characterSet = fromMaybe (detectCharacterSet parsedExpression) chosenCharacterSet+                 case transitivity of                     Transitive ->                         for_ parsedExpression $ \import_ -> do                             maybeFilepath <- Dhall.Import.dependencyToFile status import_                              for_ maybeFilepath $ \filepath ->-                                go (PossiblyTransitiveInputFile filepath Transitive)+                                go (InputFile filepath)                      NonTransitive ->                         return ()@@ -835,23 +931,23 @@                 let modifiedText = Pretty.Text.renderStrict stream <> "\n"                  case outputMode of-                    Write ->+                    Write -> do                         case input of-                            PossiblyTransitiveInputFile file _ ->+                            InputFile file ->                                 if originalText == modifiedText                                     then return ()                                     else writeDocToFile file doc -                            NonTransitiveStandardInput ->+                            StandardInput ->                                 renderDoc System.IO.stdout doc -                    Check ->-                        if originalText == modifiedText-                            then return ()-                            else do-                                let modified = "linted"+                        return (Right ()) -                                Control.Exception.throwIO CheckFailed{ command = "lint", ..}+                    Check ->+                        return $+                            if originalText == modifiedText+                                then Right ()+                                else Left CheckFailed{..}          Encode {..} -> do             expression <- getExpression file@@ -898,7 +994,7 @@                 else do                     let doc =                             Dhall.Pretty.prettyCharacterSet-                                characterSet+                                (fromMaybe Unicode chosenCharacterSet) -- default to Unicode                                 (Dhall.Core.renote expression :: Expr Src Import)                      renderDoc System.IO.stdout doc@@ -947,7 +1043,7 @@              let normalizedExpression = Dhall.Core.normalize resolvedExpression -            DirectoryTree.toDirectoryTree path normalizedExpression+            DirectoryTree.toDirectoryTree allowSeparators path normalizedExpression          Dhall.Main.Schemas{..} ->             Dhall.Schemas.schemasCommand Dhall.Schemas.Schemas{ input = file, ..}@@ -961,6 +1057,13 @@                 let denoted :: Expr Void Import                     denoted = Dhall.Core.denote expression                 in Text.Pretty.Simple.pPrintNoColor denoted++        Package {..} -> do+            let options = appEndo+                    (maybe mempty (Endo . set Dhall.Package.characterSet) chosenCharacterSet+                    <> packageOptions+                    ) Dhall.Package.defaultOptions+            writePackage options packageFiles  -- | Entry point for the @dhall@ executable main :: IO ()
src/Dhall/Map.hs view
@@ -1,9 +1,11 @@-{-# LANGUAGE DeriveAnyClass     #-}-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE DeriveGeneric      #-}-{-# LANGUAGE DeriveLift         #-}-{-# LANGUAGE ExplicitForAll     #-}-{-# LANGUAGE TypeFamilies       #-}+{-# LANGUAGE DeriveAnyClass        #-}+{-# LANGUAGE DeriveDataTypeable    #-}+{-# LANGUAGE DeriveGeneric         #-}+{-# LANGUAGE DeriveLift            #-}+{-# LANGUAGE ExplicitForAll        #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeFamilies          #-}  -- | `Map` type used to represent records and unions @@ -33,6 +35,7 @@       -- * Deletion/Update     , delete     , filter+    , partition     , restrictKeys     , withoutKeys     , mapMaybe@@ -75,9 +78,12 @@ import Language.Haskell.TH.Syntax (Lift) import Prelude                    hiding (filter, lookup) +import qualified Data.Foldable.WithIndex    as Foldable.WithIndex+import qualified Data.Functor.WithIndex     as Functor.WithIndex import qualified Data.List-import qualified Data.Map+import qualified Data.Map.Strict import qualified Data.Set+import qualified Data.Traversable.WithIndex as Traversable.WithIndex import qualified GHC.Exts import qualified Prelude @@ -88,7 +94,7 @@     This is done primarily to avoid a dependency on @insert-ordered-containers@     and also to improve performance -}-data Map k v = Map (Data.Map.Map k v) (Keys k)+data Map k v = Map (Data.Map.Strict.Map k v) (Keys k)     deriving (Data, Generic, Lift, NFData)  data Keys a@@ -98,7 +104,7 @@  instance (Ord k, Eq v) => Eq (Map k v) where   m1 == m2 =-      Data.Map.size (toMap m1) == Data.Map.size (toMap m2)+      Data.Map.Strict.size (toMap m1) == Data.Map.Strict.size (toMap m2)       && toList m1 == toList m2   {-# INLINABLE (==) #-} @@ -141,7 +147,7 @@ prop> \x -> mempty <> x == (x :: Map Int Int) -} instance Ord k => Monoid (Map k v) where-    mempty = Map Data.Map.empty (Original [])+    mempty = Map Data.Map.Strict.empty (Original [])     {-# INLINABLE mempty #-}  instance (Show k, Show v, Ord k) => Show (Map k v) where@@ -157,6 +163,18 @@      toList = Dhall.Map.toList +instance Ord k => Foldable.WithIndex.FoldableWithIndex k (Map k) where+    ifoldMap = foldMapWithKey+    {-# INLINABLE ifoldMap #-}++instance Functor.WithIndex.FunctorWithIndex k (Map k) where+    imap = mapWithKey+    {-# INLINABLE imap #-}++instance Ord k => Traversable.WithIndex.TraversableWithIndex k (Map k) where+    itraverse = traverseWithKey+    {-# INLINABLE itraverse #-}+ -- | Create an empty `Map` empty :: Ord k => Map k v empty = mempty@@ -169,7 +187,7 @@ singleton :: k -> v -> Map k v singleton k v = Map m ks   where-    m = Data.Map.singleton k v+    m = Data.Map.Strict.singleton k v      ks = Original [k] {-# INLINABLE singleton #-}@@ -193,7 +211,7 @@ fromList :: Ord k => [(k, v)] -> Map k v fromList kvs = Map m ks   where-    m = Data.Map.fromList kvs+    m = Data.Map.Strict.fromList kvs      ks = Original (nubOrd (map fst kvs)) {-# INLINABLE fromList #-}@@ -206,13 +224,13 @@ fromListWithKey :: Ord k => (k -> v -> v -> v) -> [(k, v)] -> Map k v fromListWithKey f kvs = Map m ks   where-    m = Data.Map.fromListWithKey f kvs+    m = Data.Map.Strict.fromListWithKey f kvs      ks = Original (nubOrd (map fst kvs)) {-# INLINABLE fromListWithKey #-} --- | Create a `Map` from a @"Data.Map".`Data.Map.Map`@-fromMap :: Data.Map.Map k v -> Map k v+-- | Create a `Map` from a @"Data.Map.Strict".`Data.Map.Strict.Map`@+fromMap :: Data.Map.Strict.Map k v -> Map k v fromMap m = Map m Sorted  {-| Remove duplicates from a  list@@ -241,7 +259,7 @@ unorderedSingleton :: k -> v -> Map k v unorderedSingleton k v = Map m Sorted   where-    m = Data.Map.singleton k v+    m = Data.Map.Strict.singleton k v {-# INLINABLE unorderedSingleton #-}  {-| Create a `Map` from a list of key-value pairs@@ -258,7 +276,7 @@ unorderedFromList :: Ord k => [(k, v)] -> Map k v unorderedFromList kvs = Map m Sorted   where-    m = Data.Map.fromList kvs+    m = Data.Map.Strict.fromList kvs {-# INLINABLE unorderedFromList #-}  {-| Sort the keys of a `Map`, forgetting the original ordering@@ -283,7 +301,7 @@ -} isSorted :: Eq k => Map k v -> Bool isSorted (Map _ Sorted)        = True-isSorted (Map m (Original ks)) = Data.Map.keys m == ks -- Or shortcut to False here?+isSorted (Map m (Original ks)) = Data.Map.Strict.keys m == ks -- Or shortcut to False here? {-# INLINABLE isSorted #-}  {-| Insert a key-value pair into a `Map`, overriding any previous value stored@@ -297,10 +315,10 @@ fromList [("C",1),("A",3)] -} insert :: Ord k => k -> v -> Map k v -> Map k v-insert k v (Map m Sorted)        = Map (Data.Map.insert k v m) Sorted+insert k v (Map m Sorted)        = Map (Data.Map.Strict.insert k v m) Sorted insert k v (Map m (Original ks)) = Map m' (Original ks')   where-    (mayOldV, m') = Data.Map.insertLookupWithKey (\_k new _old -> new) k v m+    (mayOldV, m') = Data.Map.Strict.insertLookupWithKey (\_k new _old -> new) k v m      ks' | Just _ <- mayOldV = ks         | otherwise         = k : ks@@ -315,10 +333,10 @@ fromList [("C",3),("A",3)] -} insertWith :: Ord k => (v -> v -> v) -> k -> v -> Map k v -> Map k v-insertWith f k v (Map m Sorted)        = Map (Data.Map.insertWith f k v m) Sorted+insertWith f k v (Map m Sorted)        = Map (Data.Map.Strict.insertWith f k v m) Sorted insertWith f k v (Map m (Original ks)) = Map m' (Original ks')   where-    (mayOldV, m') = Data.Map.insertLookupWithKey (\_k new old -> f new old) k v m+    (mayOldV, m') = Data.Map.Strict.insertLookupWithKey (\_k new old -> f new old) k v m      ks' | Just _ <- mayOldV = ks         | otherwise         = k : ks@@ -334,7 +352,7 @@ delete :: Ord k => k -> Map k v -> Map k v delete k (Map m ks) = Map m' ks'   where-    m' = Data.Map.delete k m+    m' = Data.Map.Strict.delete k m      ks' = case ks of         Sorted        -> Sorted@@ -351,11 +369,26 @@ filter :: Ord k => (a -> Bool) -> Map k a -> Map k a filter predicate (Map m ks) = Map m' ks'   where-    m' = Data.Map.filter predicate m+    m' = Data.Map.Strict.filter predicate m -    ks' = filterKeys (\k -> Data.Map.member k m') ks+    ks' = filterKeys (\k -> Data.Map.Strict.member k m') ks {-# INLINABLE filter #-} +{-| Split the map into values that do and don't satisfy the predicate++>>> partition even (fromList [("C",3),("B",2),("A",1)])+(fromList [("B",2)],fromList [("C",3),("A",1)])+>>> partition odd (fromList [("C",3),("B",2),("A",1)])+(fromList [("C",3),("A",1)],fromList [("B",2)])+-}+partition :: Ord k => (a -> Bool) -> Map k a -> (Map k a, Map k a)+partition predicate (Map m ks) = (Map mpass kpass, Map mfail kfail)+  where+    (mpass, mfail) = Data.Map.Strict.partition predicate m++    (kpass, kfail) = partitionKeys (\k -> Data.Map.Strict.member k mpass) ks+{-# INLINABLE partition #-}+ {-| 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"])@@ -364,7 +397,7 @@ restrictKeys :: Ord k => Map k a -> Data.Set.Set k -> Map k a restrictKeys (Map m ks) s = Map m' ks'   where-    m' = Data.Map.restrictKeys m s+    m' = Data.Map.Strict.restrictKeys m s      ks' = filterKeys (\k -> Data.Set.member k s) ks {-# INLINABLE restrictKeys #-}@@ -377,7 +410,7 @@ withoutKeys :: Ord k => Map k a -> Data.Set.Set k -> Map k a withoutKeys (Map m ks) s = Map m' ks'   where-    m' = Data.Map.withoutKeys m s+    m' = Data.Map.Strict.withoutKeys m s      ks' = filterKeys (\k -> Data.Set.notMember k s) ks {-# INLINABLE withoutKeys #-}@@ -391,9 +424,9 @@ mapMaybe :: Ord k => (a -> Maybe b) -> Map k a -> Map k b mapMaybe f (Map m ks) = Map m' ks'   where-    m' = Data.Map.mapMaybe f m+    m' = Data.Map.Strict.mapMaybe f m -    ks' = filterKeys (\k -> Data.Map.member k m') ks+    ks' = filterKeys (\k -> Data.Map.Strict.member k m') ks {-# INLINABLE mapMaybe #-}  {-| Retrieve a key from a `Map`@@ -408,7 +441,7 @@ Nothing -} lookup :: Ord k => k -> Map k v -> Maybe v-lookup k (Map m _) = Data.Map.lookup k m+lookup k (Map m _) = Data.Map.Strict.lookup k m {-# INLINABLE lookup #-}  {-| Retrieve the first key, value of the 'Map', if present,@@ -426,9 +459,9 @@ uncons :: Ord k => Map k v -> Maybe (k, v, Map k v) uncons (Map _ (Original []))     = Nothing uncons (Map m (Original (k:ks))) =-    Just (k, m Data.Map.! k, Map (Data.Map.delete k m) (Original ks))+    Just (k, m Data.Map.Strict.! k, Map (Data.Map.Strict.delete k m) (Original ks)) uncons (Map m Sorted)-  | Just ((k, v), m') <- Data.Map.minViewWithKey m = Just (k, v, Map m' Sorted)+  | Just ((k, v), m') <- Data.Map.Strict.minViewWithKey m = Just (k, v, Map m' Sorted)   | otherwise                                      = Nothing {-# INLINABLE uncons #-} @@ -444,7 +477,7 @@ False -} member :: Ord k => k -> Map k v -> Bool-member k (Map m _) = Data.Map.member k m+member k (Map m _) = Data.Map.Strict.member k m {-# INLINABLE member #-}  {-|@@ -452,7 +485,7 @@ 1 -} size :: Map k v -> Int-size (Map m _) = Data.Map.size m+size (Map m _) = Data.Map.Strict.size m {-# INLINABLE size #-}  {-| Combine two `Map`s, preferring keys from the first `Map`@@ -467,11 +500,11 @@ union :: Ord k => Map k v -> Map k v -> Map k v union (Map mL ksL) (Map mR ksR) = Map m ks   where-    m = Data.Map.union mL mR+    m = Data.Map.Strict.union mL mR      ks = case (ksL, ksR) of         (Original l, Original r) -> Original $-            l <|> Prelude.filter (\k -> Data.Map.notMember k mL) r+            l <|> Prelude.filter (\k -> Data.Map.Strict.notMember k mL) r         _                        -> Sorted {-# INLINABLE union #-} @@ -485,11 +518,11 @@ unionWith :: Ord k => (v -> v -> v) -> Map k v -> Map k v -> Map k v unionWith combine (Map mL ksL) (Map mR ksR) = Map m ks   where-    m = Data.Map.unionWith combine mL mR+    m = Data.Map.Strict.unionWith combine mL mR      ks = case (ksL, ksR) of         (Original l, Original r) -> Original $-            l <|> Prelude.filter (\k -> Data.Map.notMember k mL) r+            l <|> Prelude.filter (\k -> Data.Map.Strict.notMember k mL) r         _                        -> Sorted {-# INLINABLE unionWith #-} @@ -510,7 +543,7 @@     -> Map k c outerJoin fa fb fab (Map ma ksA) (Map mb ksB) = Map m ks   where-    m = Data.Map.mergeWithKey+    m = Data.Map.Strict.mergeWithKey             (\k a b -> Just (fab k a b))             (fmap fa)             (fmap fb)@@ -519,7 +552,7 @@      ks = case (ksA, ksB) of         (Original l, Original r) -> Original $-            l <|> Prelude.filter (\k -> Data.Map.notMember k ma) r+            l <|> Prelude.filter (\k -> Data.Map.Strict.notMember k ma) r         _                        -> Sorted {-# INLINABLE outerJoin #-} @@ -534,10 +567,10 @@ intersection :: Ord k => Map k a -> Map k b -> Map k a intersection (Map mL ksL) (Map mR _) = Map m ks   where-    m = Data.Map.intersection mL mR+    m = Data.Map.Strict.intersection mL mR      -- Or forget order unless both maps are ordered?!-    ks = filterKeys (\k -> Data.Map.member k m) ksL+    ks = filterKeys (\k -> Data.Map.Strict.member k m) ksL {-# INLINABLE intersection #-}  {-| Combine two `Map`s on their shared keys, using the supplied function to@@ -549,10 +582,10 @@ intersectionWith :: Ord k => (a -> b -> c) -> Map k a -> Map k b -> Map k c intersectionWith combine (Map mL ksL) (Map mR _) = Map m ks   where-    m = Data.Map.intersectionWith combine mL mR+    m = Data.Map.Strict.intersectionWith combine mL mR      -- Or forget order unless both maps are ordered?!-    ks = filterKeys (\k -> Data.Map.member k m) ksL+    ks = filterKeys (\k -> Data.Map.Strict.member k m) ksL {-# INLINABLE intersectionWith #-}  {-| Compute the difference of two `Map`s by subtracting all keys from the@@ -564,9 +597,9 @@ difference :: Ord k => Map k a -> Map k b -> Map k a difference (Map mL ksL) (Map mR _) = Map m ks   where-    m = Data.Map.difference mL mR+    m = Data.Map.Strict.difference mL mR -    ks = filterKeys (\k -> Data.Map.notMember k mR) ksL+    ks = filterKeys (\k -> Data.Map.Strict.notMember k mR) ksL {-# INLINABLE difference #-}  {-| Fold all of the key-value pairs in a `Map`, in their original order@@ -575,7 +608,7 @@ ("BA",[1,2]) -} foldMapWithKey :: (Monoid m, Ord k) => (k -> a -> m) -> Map k a -> m-foldMapWithKey f (Map m Sorted) = Data.Map.foldMapWithKey f m+foldMapWithKey f (Map m Sorted) = Data.Map.Strict.foldMapWithKey f m foldMapWithKey f m              = foldMap (uncurry f) (toList m) {-# INLINABLE foldMapWithKey #-} @@ -595,7 +628,7 @@ mapWithKey :: (k -> a -> b) -> Map k a -> Map k b mapWithKey f (Map m ks) = Map m' ks   where-    m' = Data.Map.mapWithKey f m+    m' = Data.Map.Strict.mapWithKey f m {-# INLINABLE mapWithKey #-}  {-| Traverse all of the key-value pairs in a `Map`, in their original order@@ -606,9 +639,9 @@ traverseWithKey     :: Ord k => Applicative f => (k -> a -> f b) -> Map k a -> f (Map k b) traverseWithKey f (Map m Sorted) =-    fmap (\m' -> Map m' Sorted) (Data.Map.traverseWithKey f m)-traverseWithKey f m =-    fmap fromList (traverse f' (toList m))+    fmap (\m' -> Map m' Sorted) (Data.Map.Strict.traverseWithKey f m)+traverseWithKey f m@(Map _ ks) =+    flip Map ks . Data.Map.Strict.fromList <$> traverse f' (toList m)   where     f' (k, a) = fmap ((,) k) (f k a) {-# INLINABLE traverseWithKey #-}@@ -619,7 +652,7 @@ unorderedTraverseWithKey     :: Ord k => Applicative f => (k -> a -> f b) -> Map k a -> f (Map k b) unorderedTraverseWithKey f (Map m ks) =-    fmap (\m' -> Map m' ks) (Data.Map.traverseWithKey f m)+    fmap (\m' -> Map m' ks) (Data.Map.Strict.traverseWithKey f m) {-# INLINABLE unorderedTraverseWithKey #-}  {-| Traverse all of the key-value pairs in a 'Map', not preserving their@@ -631,7 +664,7 @@ unorderedTraverseWithKey_     :: Ord k => Applicative f => (k -> a -> f ()) -> Map k a -> f () unorderedTraverseWithKey_ f (Map m _) =-    Data.Map.foldlWithKey' (\acc k v -> acc *> f k v) (pure ()) m+    Data.Map.Strict.foldlWithKey' (\acc k v -> acc *> f k v) (pure ()) m {-# INLINABLE unorderedTraverseWithKey_ #-}  {-| Convert a `Map` to a list of key-value pairs in the original order of keys@@ -640,22 +673,22 @@ [("B",1),("A",2)] -} toList :: Ord k => Map k v -> [(k, v)]-toList (Map m Sorted)        = Data.Map.toList m-toList (Map m (Original ks)) = fmap (\k -> (k, m Data.Map.! k)) ks+toList (Map m Sorted)        = Data.Map.Strict.toList m+toList (Map m (Original ks)) = fmap (\k -> (k, m Data.Map.Strict.! k)) ks {-# INLINABLE toList #-}  {-| Convert a `Map` to a list of key-value pairs in ascending order of keys -} toAscList :: Map k v -> [(k, v)]-toAscList (Map m _) = Data.Map.toAscList m+toAscList (Map m _) = Data.Map.Strict.toAscList m {-# INLINABLE toAscList #-} -{-| Convert a @"Dhall.Map".`Map`@ to a @"Data.Map".`Data.Map.Map`@+{-| Convert a @"Dhall.Map".`Map`@ to a @"Data.Map.Strict".`Data.Map.Strict.Map`@  >>> toMap (fromList [("B",1),("A",2)]) -- Order is lost upon conversion fromList [("A",2),("B",1)] -}-toMap :: Map k v -> Data.Map.Map k v+toMap :: Map k v -> Data.Map.Strict.Map k v toMap (Map m _) = m {-# INLINABLE toMap #-} @@ -665,7 +698,7 @@ ["B","A"] -} keys :: Map k v -> [k]-keys (Map m Sorted)        = Data.Map.keys m+keys (Map m Sorted)        = Data.Map.Strict.keys m keys (Map _ (Original ks)) = ks {-# INLINABLE keys #-} @@ -675,8 +708,8 @@ [1,2] -} elems :: Ord k => Map k v -> [v]-elems (Map m Sorted)        = Data.Map.elems m-elems (Map m (Original ks)) = fmap (\k -> m Data.Map.! k) ks+elems (Map m Sorted)        = Data.Map.Strict.elems m+elems (Map m (Original ks)) = fmap (\k -> m Data.Map.Strict.! k) ks {-# INLINABLE elems #-}  {-| Return the @"Data.Set".'Data.Set.Set'@ of the keys@@ -685,13 +718,20 @@ fromList ["A","B"] -} keysSet :: Map k v -> Data.Set.Set k-keysSet (Map m _) = Data.Map.keysSet m+keysSet (Map m _) = Data.Map.Strict.keysSet m {-# INLINABLE keysSet #-}  filterKeys :: (a -> Bool) -> Keys a -> Keys a filterKeys _ Sorted        = Sorted filterKeys f (Original ks) = Original (Prelude.filter f ks) {-# INLINABLE filterKeys #-}++partitionKeys :: (a -> Bool) -> Keys a -> (Keys a, Keys a)+partitionKeys _ Sorted        = (Sorted, Sorted)+partitionKeys f (Original ks) =+    let (kpass, kfail) = Data.List.partition f ks+    in (Original kpass, Original kfail)+{-# INLINABLE partitionKeys #-}  {- $setup >>> import Test.QuickCheck (Arbitrary(..), oneof)
+ src/Dhall/Marshal/Decode.hs view
@@ -0,0 +1,1712 @@+{-# LANGUAGE ApplicativeDo              #-}+{-# LANGUAGE CPP                        #-}+{-# LANGUAGE ConstraintKinds            #-}+{-# LANGUAGE DefaultSignatures          #-}+{-# LANGUAGE DeriveFunctor              #-}+{-# LANGUAGE DerivingStrategies         #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses      #-}+{-# LANGUAGE NamedFieldPuns             #-}+{-# LANGUAGE OverloadedStrings          #-}+{-# LANGUAGE PolyKinds                  #-}+{-# LANGUAGE RankNTypes                 #-}+{-# LANGUAGE RecordWildCards            #-}+{-# LANGUAGE ScopedTypeVariables        #-}+{-# LANGUAGE StandaloneDeriving         #-}+{-# 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+-}++module Dhall.Marshal.Decode+    ( -- * General+      Decoder (..)+    , FromDhall(..)+    , Interpret+    , auto++      -- * Building decoders+      -- ** Simple decoders+    , bool+    , unit+    , void+      -- ** Numbers+    , natural+    , word+    , word8+    , word16+    , word32+    , word64+    , integer+    , int+    , int8+    , int16+    , int32+    , int64+    , scientific+    , double+      -- ** Bytes+    , lazyBytes+    , strictBytes+    , shortBytes+      -- ** Textual+    , string+    , lazyText+    , strictText+    , shortText+      -- ** Time+    , timeOfDay+    , day+    , timeZone+    , localTime+    , zonedTime+    , utcTime+    , dayOfWeek+      -- ** Containers+    , maybe+    , pair+    , sequence+    , list+    , vector+    , setFromDistinctList+    , setIgnoringDuplicates+    , hashSetFromDistinctList+    , hashSetIgnoringDuplicates+    , Dhall.Marshal.Decode.map+    , hashMap+    , pairFromMapEntry+      -- ** Functions+    , function+    , functionWith+      -- ** Records+    , RecordDecoder(..)+    , record+    , field+      -- ** Unions+    , UnionDecoder(..)+    , union+    , constructor++      -- * Generic decoding+    , GenericFromDhall(..)+    , GenericFromDhallUnion(..)+    , genericAuto+    , genericAutoWith+    , genericAutoWithInputNormalizer++    -- * Decoding errors+    , DhallErrors(..)+    , showDhallErrors+    , InvalidDecoder(..)+    -- ** Extraction errors+    , ExtractErrors+    , ExtractError(..)+    , Extractor+    , typeError+    , extractError+    , MonadicExtractor+    , toMonadic+    , fromMonadic+    -- ** Typing errors+    , ExpectedTypeErrors+    , ExpectedTypeError(..)+    , Expector++    -- * Miscellaneous+    , InputNormalizer(..)+    , defaultInputNormalizer+    , InterpretOptions(..)+    , SingletonConstructors(..)+    , defaultInterpretOptions+    , Result++    -- * Re-exports+    , Natural+    , Seq+    , Text+    , Vector+    , Generic+    ) where+++import Control.Applicative              (empty, liftA2)+import Control.Exception                (Exception)+import Control.Monad                    (guard)+import Control.Monad.Trans.State.Strict+import Data.Coerce                      (coerce)+import Data.Either.Validation+    ( Validation (..)+    , eitherToValidation+    , validationToEither+    )+import Data.Functor.Contravariant+    ( Equivalence (..)+    , Op (..)+    , Predicate (..)+    )+import Data.Functor.Identity            (Identity (..))+import Data.Hashable                    (Hashable)+import Data.List.NonEmpty               (NonEmpty (..))+import Data.Typeable                    (Proxy (..), Typeable)+import Dhall.Parser                     (Src (..))+import Dhall.Syntax+    ( Chunks (..)+    , DhallDouble (..)+    , Expr (..)+    , FieldSelection (..)+    , FunctionBinding (..)+    , Var (..)+    )+import GHC.Generics+import Prelude                          hiding (maybe, sequence)+import Prettyprinter                    (Pretty)++import qualified Control.Applicative+import qualified Data.ByteString+import qualified Data.ByteString.Lazy+import qualified Data.ByteString.Short+import qualified Data.Foldable+import qualified Data.Functor.Compose+import qualified Data.Functor.Product+import qualified Data.HashMap.Strict   as HashMap+import qualified Data.HashSet+import qualified Data.List             as List+import qualified Data.List.NonEmpty+import qualified Data.Map+import qualified Data.Maybe+import qualified Data.Scientific+import qualified Data.Sequence+import qualified Data.Set+import qualified Data.Text+import qualified Data.Text.Lazy+import qualified Data.Text.Short+import qualified Data.Time             as Time+import qualified Data.Vector+import qualified Dhall.Core            as Core+import qualified Dhall.Map+import qualified Dhall.Util++import Dhall.Marshal.Encode+import Dhall.Marshal.Internal++-- $setup+-- >>> import Dhall (input)++{-| A @(Decoder a)@ represents a way to marshal a value of type @\'a\'@ from Dhall+    into Haskell.++    You can produce `Decoder`s either explicitly:++> example :: Decoder (Vector Text)+> example = vector text++    ... or implicitly using `auto`:++> example :: Decoder (Vector Text)+> example = auto++    You can consume `Decoder`s using the `Dhall.input` function:++> input :: Decoder a -> Text -> IO a+-}+data Decoder a = Decoder+    { extract  :: Expr Src Void -> Extractor Src Void a+    -- ^ Extracts Haskell value from the Dhall expression+    , expected :: Expector (Expr Src Void)+    -- ^ Dhall type of the Haskell value+    }+    deriving (Functor)++{-| Any value that implements `FromDhall` can be automatically decoded based on+    the inferred return type of `Dhall.input`.++>>> input auto "[1, 2, 3]" :: IO (Vector Natural)+[1,2,3]+>>> input auto "toMap { a = False, b = True }" :: IO (Map Text Bool)+fromList [("a",False),("b",True)]++    This class auto-generates a default implementation for types that+    implement `Generic`.  This does not auto-generate an instance for recursive+    types.++    The default instance can be tweaked using 'genericAutoWith'/'genericAutoWithInputNormalizer'+    and custom 'InterpretOptions', or using+    [DerivingVia](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-DerivingVia)+    and 'Dhall.Deriving.Codec' from "Dhall.Deriving".+-}+class FromDhall a where+    autoWith :: InputNormalizer -> Decoder a+    default autoWith+        :: (Generic a, GenericFromDhall a (Rep a)) => InputNormalizer -> Decoder a+    autoWith _ = genericAuto++-- | A compatibility alias for `FromDhall`.+type Interpret = FromDhall+{-# DEPRECATED Interpret "Use FromDhall instead" #-}++{-| Use the default input normalizer for interpreting an input.++> auto = autoWith defaultInputNormalizer+-}+auto :: FromDhall a => Decoder a+auto = autoWith defaultInputNormalizer++++instance FromDhall Void where+    autoWith _ = void++instance FromDhall () where+    autoWith _ = unit++instance FromDhall Bool where+    autoWith _ = bool++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++instance FromDhall Double where+    autoWith _ = double++instance FromDhall Data.ByteString.Short.ShortByteString where+    autoWith _ = shortBytes++instance FromDhall Data.ByteString.Lazy.ByteString where+    autoWith _ = lazyBytes++instance FromDhall Data.ByteString.ByteString where+    autoWith _ = strictBytes++instance {-# OVERLAPS #-} FromDhall [Char] where+    autoWith _ = string++instance FromDhall Data.Text.Short.ShortText where+    autoWith _ = shortText++instance FromDhall Data.Text.Lazy.Text where+    autoWith _ = lazyText++instance FromDhall Text where+    autoWith _ = strictText++instance FromDhall a => FromDhall (Identity a) where+    autoWith opts = Identity <$> autoWith opts++instance FromDhall a => FromDhall (Maybe a) where+    autoWith opts = maybe (autoWith opts)++instance FromDhall a => FromDhall (Seq a) where+    autoWith opts = sequence (autoWith opts)++instance FromDhall a => FromDhall [a] where+    autoWith opts = list (autoWith opts)++instance FromDhall a => FromDhall (Vector a) where+    autoWith opts = vector (autoWith opts)++instance FromDhall Time.TimeOfDay where+    autoWith _ = timeOfDay++instance FromDhall Time.Day where+    autoWith _ = day++instance FromDhall Time.TimeZone where+    autoWith _ = timeZone++instance FromDhall Time.LocalTime where+    autoWith _ = localTime++instance FromDhall Time.ZonedTime where+    autoWith _ = zonedTime++instance FromDhall Time.UTCTime where+    autoWith _ = utcTime++instance FromDhall Time.DayOfWeek where+    autoWith _ = dayOfWeek++{-| Note that this instance will throw errors in the presence of duplicates in+    the list. To ignore duplicates, use `setIgnoringDuplicates`.+-}+instance (FromDhall a, Ord a, Show a) => FromDhall (Data.Set.Set a) where+    autoWith opts = setFromDistinctList (autoWith opts)++{-| Note that this instance will throw errors in the presence of duplicates in+    the list. To ignore duplicates, use `hashSetIgnoringDuplicates`.+-}+instance (FromDhall a, Hashable a, Ord a, Show a) => FromDhall (Data.HashSet.HashSet a) where+    autoWith inputNormalizer = hashSetFromDistinctList (autoWith inputNormalizer)++instance (Ord k, FromDhall k, FromDhall v) => FromDhall (Map k v) where+    autoWith inputNormalizer = Dhall.Marshal.Decode.map (autoWith inputNormalizer) (autoWith inputNormalizer)++instance (Eq k, Hashable k, FromDhall k, FromDhall v) => FromDhall (HashMap k v) where+    autoWith inputNormalizer = Dhall.Marshal.Decode.hashMap (autoWith inputNormalizer) (autoWith inputNormalizer)++instance (ToDhall a, FromDhall b) => FromDhall (a -> b) where+    autoWith inputNormalizer =+        functionWith inputNormalizer (injectWith inputNormalizer) (autoWith inputNormalizer)++instance (FromDhall a, FromDhall b) => FromDhall (a, b)++instance FromDhall (f (Result f)) => FromDhall (Result f) where+    autoWith inputNormalizer = Decoder {..}+      where+        extract (App _ expr) =+            fmap Result (Dhall.Marshal.Decode.extract (autoWith inputNormalizer) expr)+        extract expr = typeError expected expr++        expected = pure "result"++deriving newtype instance (ToDhall x) => FromDhall (Predicate x)++deriving newtype instance (ToDhall x) => FromDhall (Equivalence x)++deriving newtype instance (FromDhall b, ToDhall x) => FromDhall (Op b x)++-- | You can use this instance to marshal recursive types from Dhall to Haskell.+--+-- Here is an example use of this instance:+--+-- > {-# LANGUAGE DeriveAnyClass     #-}+-- > {-# LANGUAGE DeriveFoldable     #-}+-- > {-# LANGUAGE DeriveFunctor      #-}+-- > {-# LANGUAGE DeriveTraversable  #-}+-- > {-# LANGUAGE DeriveGeneric      #-}+-- > {-# LANGUAGE KindSignatures     #-}+-- > {-# LANGUAGE QuasiQuotes        #-}+-- > {-# LANGUAGE StandaloneDeriving #-}+-- > {-# LANGUAGE TypeFamilies       #-}+-- > {-# LANGUAGE TemplateHaskell    #-}+-- >+-- > import Data.Fix (Fix(..))+-- > import Data.Text (Text)+-- > import Dhall (FromDhall)+-- > import GHC.Generics (Generic)+-- > import Numeric.Natural (Natural)+-- >+-- > import qualified Data.Fix                 as Fix+-- > import qualified Data.Functor.Foldable    as Foldable+-- > import qualified Data.Functor.Foldable.TH as TH+-- > import qualified Dhall+-- > import qualified NeatInterpolation+-- >+-- > data Expr+-- >     = Lit Natural+-- >     | Add Expr Expr+-- >     | Mul Expr Expr+-- >     deriving (Show)+-- >+-- > TH.makeBaseFunctor ''Expr+-- >+-- > deriving instance Generic (ExprF a)+-- > deriving instance FromDhall a => FromDhall (ExprF a)+-- >+-- > example :: Text+-- > example = [NeatInterpolation.text|+-- >     \(Expr : Type)+-- > ->  let ExprF =+-- >           < LitF :+-- >               Natural+-- >           | AddF :+-- >               { _1 : Expr, _2 : Expr }+-- >           | MulF :+-- >               { _1 : Expr, _2 : Expr }+-- >           >+-- >+-- >     in      \(Fix : ExprF -> Expr)+-- >         ->  let Lit = \(x : Natural) -> Fix (ExprF.LitF x)+-- >+-- >             let Add =+-- >                       \(x : Expr)+-- >                   ->  \(y : Expr)+-- >                   ->  Fix (ExprF.AddF { _1 = x, _2 = y })+-- >+-- >             let Mul =+-- >                       \(x : Expr)+-- >                   ->  \(y : Expr)+-- >                   ->  Fix (ExprF.MulF { _1 = x, _2 = y })+-- >+-- >             in  Add (Mul (Lit 3) (Lit 7)) (Add (Lit 1) (Lit 2))+-- > |]+-- >+-- > convert :: Fix ExprF -> Expr+-- > convert = Fix.foldFix Foldable.embed+-- >+-- > main :: IO ()+-- > main = do+-- >     x <- Dhall.input Dhall.auto example :: IO (Fix ExprF)+-- >+-- >     print (convert x :: Expr)+instance (Functor f, FromDhall (f (Result f))) => FromDhall (Fix f) where+    autoWith inputNormalizer = Decoder {..}+      where+        extract expr0 = extract0 expr0+          where+            die = typeError expected expr0++            extract0 (Lam _ (FunctionBinding { functionBindingVariable = x }) expr) =+                extract1 (rename x "result" expr)+            extract0  _             = die++            extract1 (Lam _ (FunctionBinding { functionBindingVariable = y }) expr) =+                extract2 (rename y "Make" expr)+            extract1  _             = die++            extract2 expr = fmap resultToFix (Dhall.Marshal.Decode.extract (autoWith inputNormalizer) expr)++            rename a b expr+                | a /= b    = Core.subst (V a 0) (Var (V b 0)) (Core.shift 1 (V b 0) expr)+                | otherwise = expr++        expected = (\x -> Pi mempty "result" (Const Core.Type) (Pi mempty "Make" (Pi mempty "_" x "result") "result"))+            <$> Dhall.Marshal.Decode.expected (autoWith inputNormalizer :: Decoder (f (Result f)))++resultToFix :: Functor f => Result f -> Fix f+resultToFix (Result x) = Fix (fmap resultToFix x)++++{-| This is the underlying class that powers the `FromDhall` class's support+    for automatically deriving a generic implementation.+-}+class GenericFromDhall t f where+    genericAutoWithNormalizer :: Proxy t -> InputNormalizer -> InterpretOptions -> State Int (Decoder (f a))++instance GenericFromDhall t f => GenericFromDhall t (M1 D d f) where+    genericAutoWithNormalizer p inputNormalizer options = do+        res <- genericAutoWithNormalizer p inputNormalizer options+        pure (fmap M1 res)++instance GenericFromDhall t V1 where+    genericAutoWithNormalizer _ _ _ = pure Decoder {..}+      where+        extract expr = typeError expected expr++        expected = pure $ Union mempty++instance GenericFromDhallUnion t (f :+: g) => GenericFromDhall t (f :+: g) where+  genericAutoWithNormalizer p inputNormalizer options =+    pure (union (genericUnionAutoWithNormalizer p inputNormalizer options))++instance GenericFromDhall t f => GenericFromDhall t (M1 C c f) where+    genericAutoWithNormalizer p inputNormalizer options = do+        res <- genericAutoWithNormalizer p inputNormalizer options+        pure (fmap M1 res)++instance GenericFromDhall t U1 where+    genericAutoWithNormalizer _ _ _ = pure (Decoder {..})+      where+        extract _ = pure U1++        expected = pure expected'++        expected' = Record (Dhall.Map.fromList [])++instance (GenericFromDhall t (f :*: g), GenericFromDhall t (h :*: i)) => GenericFromDhall t ((f :*: g) :*: (h :*: i)) where+    genericAutoWithNormalizer p inputNormalizer options = do+        Decoder extractL expectedL <- genericAutoWithNormalizer p inputNormalizer options+        Decoder extractR expectedR <- genericAutoWithNormalizer p inputNormalizer options++        let ktsL = unsafeExpectRecord "genericAutoWithNormalizer (:*:)" <$> expectedL+        let ktsR = unsafeExpectRecord "genericAutoWithNormalizer (:*:)" <$> expectedR++        let expected = Record <$> (Dhall.Map.union <$> ktsL <*> ktsR)++        let extract expression =+                liftA2 (:*:) (extractL expression) (extractR expression)++        return (Decoder {..})++instance (GenericFromDhall t (f :*: g), Selector s, FromDhall a) => GenericFromDhall t ((f :*: g) :*: M1 S s (K1 i a)) where+    genericAutoWithNormalizer p inputNormalizer options@InterpretOptions{..} = do+        let nR :: M1 S s (K1 i a) r+            nR = undefined++        nameR <- fmap fieldModifier (getSelName nR)++        Decoder extractL expectedL <- genericAutoWithNormalizer p inputNormalizer options++        let Decoder extractR expectedR = autoWith inputNormalizer++        let ktsL = unsafeExpectRecord "genericAutoWithNormalizer (:*:)" <$> expectedL++        let expected = Record <$> (Dhall.Map.insert nameR . Core.makeRecordField <$> expectedR <*> ktsL)++        let extract expression = do+                let die = typeError expected expression++                case expression of+                    RecordLit kvs ->+                        case Core.recordFieldValue <$> Dhall.Map.lookup nameR kvs of+                            Just expressionR ->+                                liftA2 (:*:)+                                    (extractL expression)+                                    (fmap (M1 . K1) (extractR expressionR))+                            _ -> die+                    _ -> die++        return (Decoder {..})++instance (Selector s, FromDhall a, GenericFromDhall t (f :*: g)) => GenericFromDhall t (M1 S s (K1 i a) :*: (f :*: g)) where+    genericAutoWithNormalizer p inputNormalizer options@InterpretOptions{..} = do+        let nL :: M1 S s (K1 i a) r+            nL = undefined++        nameL <- fmap fieldModifier (getSelName nL)++        let Decoder extractL expectedL = autoWith inputNormalizer++        Decoder extractR expectedR <- genericAutoWithNormalizer p inputNormalizer options++        let ktsR = unsafeExpectRecord "genericAutoWithNormalizer (:*:)" <$> expectedR++        let expected = Record <$> (Dhall.Map.insert nameL . Core.makeRecordField <$> expectedL <*> ktsR)++        let extract expression = do+                let die = typeError expected expression++                case expression of+                    RecordLit kvs ->+                        case Core.recordFieldValue <$> Dhall.Map.lookup nameL kvs of+                            Just expressionL ->+                                liftA2 (:*:)+                                    (fmap (M1 . K1) (extractL expressionL))+                                    (extractR expression)+                            _ -> die+                    _ -> die++        return (Decoder {..})++instance {-# OVERLAPPING #-} GenericFromDhall a1 (M1 S s1 (K1 i1 a1) :*: M1 S s2 (K1 i2 a2)) where+    genericAutoWithNormalizer _ _ _ = pure $ Decoder+        { extract = \_ -> Failure $ DhallErrors $ pure $ ExpectedTypeError RecursiveTypeError+        , expected = Failure $ DhallErrors $ pure RecursiveTypeError+        }++instance {-# OVERLAPPING #-} GenericFromDhall a2 (M1 S s1 (K1 i1 a1) :*: M1 S s2 (K1 i2 a2)) where+    genericAutoWithNormalizer _ _ _ = pure $ Decoder+        { extract = \_ -> Failure $ DhallErrors $ pure $ ExpectedTypeError RecursiveTypeError+        , expected = Failure $ DhallErrors $ pure RecursiveTypeError+        }++instance {-# OVERLAPPABLE #-} (Selector s1, Selector s2, FromDhall a1, FromDhall a2) => GenericFromDhall t (M1 S s1 (K1 i1 a1) :*: M1 S s2 (K1 i2 a2)) where+    genericAutoWithNormalizer _ inputNormalizer InterpretOptions{..} = do+        let nL :: M1 S s1 (K1 i1 a1) r+            nL = undefined++        let nR :: M1 S s2 (K1 i2 a2) r+            nR = undefined++        nameL <- fmap fieldModifier (getSelName nL)+        nameR <- fmap fieldModifier (getSelName nR)++        let Decoder extractL expectedL = autoWith inputNormalizer+        let Decoder extractR expectedR = autoWith inputNormalizer++        let expected = do+                l <- Core.makeRecordField <$> expectedL+                r <- Core.makeRecordField <$> expectedR+                pure $ Record+                    (Dhall.Map.fromList+                        [ (nameL, l)+                        , (nameR, r)+                        ]+                    )++        let extract expression = do+                let die = typeError expected expression++                case expression of+                    RecordLit kvs ->+                        case liftA2 (,) (Dhall.Map.lookup nameL kvs) (Dhall.Map.lookup nameR kvs) of+                            Just (expressionL, expressionR) ->+                                liftA2 (:*:)+                                    (fmap (M1 . K1) (extractL $ Core.recordFieldValue expressionL))+                                    (fmap (M1 . K1) (extractR $ Core.recordFieldValue expressionR))+                            Nothing -> die+                    _ -> die++        return (Decoder {..})++instance {-# OVERLAPPING #-} GenericFromDhall a (M1 S s (K1 i a)) where+    genericAutoWithNormalizer _ _ _ = pure $ Decoder+        { extract = \_ -> Failure $ DhallErrors $ pure $ ExpectedTypeError RecursiveTypeError+        , expected = Failure $ DhallErrors $ pure RecursiveTypeError+        }++instance {-# OVERLAPPABLE #-} (Selector s, FromDhall a) => GenericFromDhall t (M1 S s (K1 i a)) where+    genericAutoWithNormalizer _ inputNormalizer InterpretOptions{..} = do+        let n :: M1 S s (K1 i a) r+            n = undefined++        name <- fmap fieldModifier (getSelName n)++        let Decoder { extract = extract', expected = expected'} = autoWith inputNormalizer++        let expected =+                case singletonConstructors of+                    Bare ->+                        expected'+                    Smart | selName n == "" ->+                        expected'+                    _ ->+                        Record . Dhall.Map.singleton name . Core.makeRecordField <$> expected'++        let extract0 expression = fmap (M1 . K1) (extract' expression)++        let extract1 expression = do+                let die = typeError expected expression++                case expression of+                    RecordLit kvs ->+                        case Core.recordFieldValue <$> Dhall.Map.lookup name kvs of+                            Just subExpression ->+                                fmap (M1 . K1) (extract' subExpression)+                            Nothing ->+                                die+                    _ -> die++        let extract =+                case singletonConstructors of+                    Bare                    -> extract0+                    Smart | selName n == "" -> extract0+                    _                       -> extract1++        return (Decoder {..})++{-| `genericAuto` is the default implementation for `auto` if you derive+    `FromDhall`.  The difference is that you can use `genericAuto` without+    having to explicitly provide a `FromDhall` instance for a type as long as+    the type derives `Generic`.+-}+genericAuto :: (Generic a, GenericFromDhall a (Rep a)) => Decoder a+genericAuto = genericAutoWith defaultInterpretOptions++{-| `genericAutoWith` is a configurable version of `genericAuto`.+-}+genericAutoWith :: (Generic a, GenericFromDhall a (Rep a)) => InterpretOptions -> Decoder a+genericAutoWith options = genericAutoWithInputNormalizer options defaultInputNormalizer++{-| `genericAutoWithInputNormalizer` is like `genericAutoWith`, but instead of+    using the `defaultInputNormalizer` it expects an custom `InputNormalizer`.+-}+genericAutoWithInputNormalizer :: (Generic a, GenericFromDhall a (Rep a)) => InterpretOptions -> InputNormalizer -> Decoder a+genericAutoWithInputNormalizer options inputNormalizer = withProxy (\p -> fmap to (evalState (genericAutoWithNormalizer p inputNormalizer options) 1))+    where+        withProxy :: (Proxy a -> Decoder a) -> Decoder a+        withProxy f = f Proxy++extractUnionConstructor+    :: Expr s a -> Maybe (Text, Expr s a, Dhall.Map.Map Text (Maybe (Expr s a)))+extractUnionConstructor (App (Field (Union kts) (Core.fieldSelectionLabel -> fld)) e) =+  return (fld, e, Dhall.Map.delete fld kts)+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)++instance (GenericFromDhallUnion t f1, GenericFromDhallUnion t f2) => GenericFromDhallUnion t (f1 :+: f2) where+  genericUnionAutoWithNormalizer p inputNormalizer options =+    (<>)+      (L1 <$> genericUnionAutoWithNormalizer p inputNormalizer options)+      (R1 <$> genericUnionAutoWithNormalizer p inputNormalizer options)++instance (Constructor c1, GenericFromDhall t f1) => GenericFromDhallUnion t (M1 C c1 f1) where+  genericUnionAutoWithNormalizer p inputNormalizer options@(InterpretOptions {..}) =+    constructor name (evalState (genericAutoWithNormalizer p inputNormalizer options) 1)+    where+      n :: M1 C c1 f1 a+      n = undefined++      name = constructorModifier (Data.Text.pack (conName n))++++{-| Decode a `Prelude.Bool`.++>>> input bool "True"+True+-}+bool :: Decoder Bool+bool = Decoder {..}+  where+    extract (BoolLit b) = pure b+    extract expr        = typeError expected expr++    expected = pure Bool++{-| Decode a `Prelude.Natural`.++>>> input natural "42"+42+-}+natural :: Decoder Natural+natural = Decoder {..}+  where+    extract (NaturalLit n) = pure n+    extract  expr          = typeError expected expr++    expected = pure Natural++{-| Decode an `Prelude.Integer`.++>>> input integer "+42"+42+-}+integer :: Decoder Integer+integer = Decoder {..}+  where+    extract (IntegerLit n) = pure n+    extract  expr          = typeError expected expr++    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`.++>>> input scientific "1e100"+1.0e100+-}+scientific :: Decoder Scientific+scientific = fmap Data.Scientific.fromFloatDigits double++{-| Decode a `Prelude.Double`.++>>> input double "42.0"+42.0+-}+double :: Decoder Double+double = Decoder {..}+  where+    extract (DoubleLit (DhallDouble n)) = pure n+    extract  expr                       = typeError expected expr++    expected = pure Double++{-| Decode a `Data.ByteString.Short.ShortByteString`++>>> input shortBytes "0x\"00FF\""+"\NUL\255"+-}+shortBytes :: Decoder Data.ByteString.Short.ShortByteString+shortBytes = fmap Data.ByteString.Short.toShort strictBytes++{-| Decode a lazy `Data.ByteString.Lazy.ByteString`.++>>> input lazyBytes "0x\"00FF\""+"\NUL\255"+-}+lazyBytes :: Decoder Data.ByteString.Lazy.ByteString+lazyBytes = fmap Data.ByteString.Lazy.fromStrict strictBytes++{-| Decode a strict `Data.ByteString.ByteString`++>>> input strictBytes "0x\"00FF\""+"\NUL\255"+-}+strictBytes :: Decoder Data.ByteString.ByteString+strictBytes = Decoder {..}+  where+    extract (BytesLit b) = pure b+    extract  expr        = typeError expected expr++    expected = pure Bytes++{-| Decode `Data.Text.Short.ShortText`.++>>> input shortText "\"Test\""+"Test"+-}+shortText :: Decoder Data.Text.Short.ShortText+shortText = fmap Data.Text.Short.fromText strictText++{-| Decode lazy `Data.Text.Lazy.Text`.++>>> input lazyText "\"Test\""+"Test"+-}+lazyText :: Decoder Data.Text.Lazy.Text+lazyText = fmap Data.Text.Lazy.fromStrict strictText++{-| Decode strict `Data.Text.Text`.++>>> input strictText "\"Test\""+"Test"+-}+strictText :: Decoder Text+strictText = Decoder {..}+  where+    extract (TextLit (Chunks [] t)) = pure t+    extract  expr                   = typeError expected expr++    expected = pure Text++{-| Decode `Time.TimeOfDay`++>>> input timeOfDay "00:00:00"+00:00:00+-}+timeOfDay :: Decoder Time.TimeOfDay+timeOfDay = Decoder {..}+  where+    extract (TimeLiteral t _) = pure t+    extract  expr             = typeError expected expr++    expected = pure Time++{-| Decode `Time.Day`++>>> input day "2000-01-01"+2000-01-01+-}+day :: Decoder Time.Day+day = Decoder {..}+  where+    extract (DateLiteral d) = pure d+    extract  expr           = typeError expected expr++    expected = pure Date++{-| Decode `Time.TimeZone`++>>> input timeZone "+00:00"++0000+-}+timeZone :: Decoder Time.TimeZone+timeZone = Decoder {..}+  where+    extract (TimeZoneLiteral z) = pure z+    extract  expr               = typeError expected expr++    expected = pure TimeZone++{-| Decode `Time.LocalTime`++>>> input localTime "2020-01-01T12:34:56"+2020-01-01 12:34:56+-}+localTime :: Decoder Time.LocalTime+localTime = record $+  Time.LocalTime+    <$> field "date" day+    <*> field "time" timeOfDay++{-| Decode `Time.ZonedTime`++>>> input zonedTime "2020-01-01T12:34:56+02:00"+2020-01-01 12:34:56 +0200+-}+zonedTime :: Decoder Time.ZonedTime+zonedTime = record $+  adapt+    <$> field "date" day+    <*> field "time" timeOfDay+    <*> field "timeZone" timeZone+  where+    adapt date time = Time.ZonedTime (Time.LocalTime date time)++{-| Decode `Time.UTCTime`++>>> input utcTime "2020-01-01T12:34:56+02:00"+2020-01-01 10:34:56 UTC+-}+utcTime :: Decoder Time.UTCTime+utcTime = Time.zonedTimeToUTC <$> zonedTime++{-| Decode `Time.DayOfWeek`++>>> input dayOfWeek "< Sunday | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday >.Monday"+Monday+-}+dayOfWeek :: Decoder Time.DayOfWeek+dayOfWeek = Decoder{..}+  where+    extract expr@(Field _ FieldSelection{ fieldSelectionLabel }) =+        case fieldSelectionLabel of+            "Sunday"    -> pure Time.Sunday+            "Monday"    -> pure Time.Monday+            "Tuesday"   -> pure Time.Tuesday+            "Wednesday" -> pure Time.Wednesday+            "Thursday"  -> pure Time.Thursday+            "Friday"    -> pure Time.Friday+            "Saturday"  -> pure Time.Saturday+            _           -> typeError expected expr+    extract expr =+        typeError expected expr++    expected =+        pure+            (Union+                (Dhall.Map.fromList+                    [ ("Sunday", Nothing)+                    , ("Monday", Nothing)+                    , ("Tuesday", Nothing)+                    , ("Wednesday", Nothing)+                    , ("Thursday", Nothing)+                    , ("Friday", Nothing)+                    , ("Saturday", Nothing)+                    ]+                )+            )++{-| Decode a `Maybe`.++>>> input (maybe natural) "Some 1"+Just 1+-}+maybe :: Decoder a -> Decoder (Maybe a)+maybe (Decoder extractIn expectedIn) = Decoder extractOut expectedOut+  where+    extractOut (Some e    ) = fmap Just (extractIn e)+    extractOut (App None _) = pure Nothing+    extractOut expr         = typeError expectedOut expr++    expectedOut = App Optional <$> expectedIn++{-| Decode a `Seq`.++>>> input (sequence natural) "[1, 2, 3]"+fromList [1,2,3]+-}+sequence :: Decoder a -> Decoder (Seq a)+sequence (Decoder extractIn expectedIn) = Decoder extractOut expectedOut+  where+    extractOut (ListLit _ es) = traverse extractIn es+    extractOut expr           = typeError expectedOut expr++    expectedOut = App List <$> expectedIn++{-| Decode a list.++>>> input (list natural) "[1, 2, 3]"+[1,2,3]+-}+list :: Decoder a -> Decoder [a]+list = fmap Data.Foldable.toList . sequence++{-| Decode a `Vector`.++>>> input (vector natural) "[1, 2, 3]"+[1,2,3]+-}+vector :: Decoder a -> Decoder (Vector a)+vector = fmap Data.Vector.fromList . list++{-| Decode a Dhall function into a Haskell function.++>>> f <- input (function inject bool) "Natural/even" :: IO (Natural -> Bool)+>>> f 0+True+>>> f 1+False+-}+function+    :: Encoder a+    -> Decoder b+    -> Decoder (a -> b)+function = functionWith defaultInputNormalizer++{-| Decode a Dhall function into a Haskell function using the specified normalizer.++>>> f <- input (functionWith defaultInputNormalizer inject bool) "Natural/even" :: IO (Natural -> Bool)+>>> f 0+True+>>> f 1+False+-}+functionWith+    :: InputNormalizer+    -> Encoder a+    -> Decoder b+    -> Decoder (a -> b)+functionWith inputNormalizer (Encoder {..}) (Decoder extractIn expectedIn) =+    Decoder extractOut expectedOut+  where+    normalizer_ = Just (getInputNormalizer inputNormalizer)++    extractOut e = pure (\i -> case extractIn (Core.normalizeWith normalizer_ (App e (embed i))) of+        Success o  -> o+        Failure _e -> error "FromDhall: You cannot decode a function if it does not have the correct type" )++    expectedOut = Pi mempty "_" declared <$> expectedIn++{-| Decode a `Data.Set.Set` from a `List`.++>>> input (setIgnoringDuplicates natural) "[1, 2, 3]"+fromList [1,2,3]++Duplicate elements are ignored.++>>> input (setIgnoringDuplicates natural) "[1, 1, 3]"+fromList [1,3]++-}+setIgnoringDuplicates :: (Ord a) => Decoder a -> Decoder (Data.Set.Set a)+setIgnoringDuplicates = fmap Data.Set.fromList . list++{-| Decode a `Data.HashSet.HashSet` from a `List`.++>>> input (hashSetIgnoringDuplicates natural) "[1, 2, 3]"+fromList [1,2,3]++Duplicate elements are ignored.++>>> input (hashSetIgnoringDuplicates natural) "[1, 1, 3]"+fromList [1,3]++-}+hashSetIgnoringDuplicates :: (Hashable a, Ord a)+                          => Decoder a+                          -> Decoder (Data.HashSet.HashSet a)+hashSetIgnoringDuplicates = fmap Data.HashSet.fromList . list++{-| Decode a `Data.Set.Set` from a `List` with distinct elements.++>>> input (setFromDistinctList natural) "[1, 2, 3]"+fromList [1,2,3]++An error is thrown if the list contains duplicates.++> >>> input (setFromDistinctList natural) "[1, 1, 3]"+> *** Exception: Error: Failed extraction+>+> The expression type-checked successfully but the transformation to the target+> type failed with the following error:+>+> One duplicate element in the list: 1+>++> >>> input (setFromDistinctList natural) "[1, 1, 3, 3]"+> *** Exception: Error: Failed extraction+>+> The expression type-checked successfully but the transformation to the target+> type failed with the following error:+>+> 2 duplicates were found in the list, including 1+>++-}+setFromDistinctList :: (Ord a, Show a) => Decoder a -> Decoder (Data.Set.Set a)+setFromDistinctList = setHelper Data.Set.size Data.Set.fromList++{-| Decode a `Data.HashSet.HashSet` from a `List` with distinct elements.++>>> input (hashSetFromDistinctList natural) "[1, 2, 3]"+fromList [1,2,3]++An error is thrown if the list contains duplicates.++> >>> input (hashSetFromDistinctList natural) "[1, 1, 3]"+> *** Exception: Error: Failed extraction+>+> The expression type-checked successfully but the transformation to the target+> type failed with the following error:+>+> One duplicate element in the list: 1+>++> >>> input (hashSetFromDistinctList natural) "[1, 1, 3, 3]"+> *** Exception: Error: Failed extraction+>+> The expression type-checked successfully but the transformation to the target+> type failed with the following error:+>+> 2 duplicates were found in the list, including 1+>++-}+hashSetFromDistinctList :: (Hashable a, Ord a, Show a)+                        => Decoder a+                        -> Decoder (Data.HashSet.HashSet a)+hashSetFromDistinctList = setHelper Data.HashSet.size Data.HashSet.fromList+++setHelper :: (Eq a, Foldable t, Show a)+          => (t a -> Int)+          -> ([a] -> t a)+          -> Decoder a+          -> Decoder (t a)+setHelper size toSet (Decoder extractIn expectedIn) = Decoder extractOut expectedOut+  where+    extractOut (ListLit _ es) = case traverse extractIn es of+        Success vSeq+            | sameSize               -> Success vSet+            | otherwise              -> extractError err+          where+            vList = Data.Foldable.toList vSeq+            vSet = toSet vList+            sameSize = size vSet == Data.Sequence.length vSeq+            duplicates = vList List.\\ Data.Foldable.toList vSet+            err | length duplicates == 1 =+                     "One duplicate element in the list: "+                     <> (Data.Text.pack $ show $ head duplicates)+                | otherwise              = Data.Text.pack $ unwords+                     [ show $ length duplicates+                     , "duplicates were found in the list, including"+                     , show $ head duplicates+                     ]+        Failure f -> Failure f+    extractOut expr = typeError expectedOut expr++    expectedOut = App List <$> expectedIn++{-| Decode a `Map` from a @toMap@ expression or generally a @Prelude.Map.Type@.++>>> input (Dhall.map strictText bool) "toMap { a = True, b = False }"+fromList [("a",True),("b",False)]+>>> input (Dhall.map strictText bool) "[ { mapKey = \"foo\", mapValue = True } ]"+fromList [("foo",True)]++If there are duplicate @mapKey@s, later @mapValue@s take precedence:++>>> let expr = "[ { mapKey = 1, mapValue = True }, { mapKey = 1, mapValue = False } ]"+>>> input (Dhall.map natural bool) expr+fromList [(1,False)]++-}+map :: Ord k => Decoder k -> Decoder v -> Decoder (Map k v)+map k v = fmap Data.Map.fromList (list (pairFromMapEntry k v))++{-| Decode a `HashMap` from a @toMap@ expression or generally a @Prelude.Map.Type@.++>>> fmap (List.sort . HashMap.toList) (input (Dhall.hashMap strictText bool) "toMap { a = True, b = False }")+[("a",True),("b",False)]+>>> fmap (List.sort . HashMap.toList) (input (Dhall.hashMap strictText bool) "[ { mapKey = \"foo\", mapValue = True } ]")+[("foo",True)]++If there are duplicate @mapKey@s, later @mapValue@s take precedence:++>>> let expr = "[ { mapKey = 1, mapValue = True }, { mapKey = 1, mapValue = False } ]"+>>> input (Dhall.hashMap natural bool) expr+fromList [(1,False)]++-}+hashMap :: (Eq k, Hashable k) => Decoder k -> Decoder v -> Decoder (HashMap k v)+hashMap k v = fmap HashMap.fromList (list (pairFromMapEntry k v))++{-| Decode a tuple from a @Prelude.Map.Entry@ record.++>>> input (pairFromMapEntry strictText natural) "{ mapKey = \"foo\", mapValue = 3 }"+("foo",3)+-}+pairFromMapEntry :: Decoder k -> Decoder v -> Decoder (k, v)+pairFromMapEntry k v = Decoder extractOut expectedOut+  where+    extractOut (RecordLit kvs)+        | Just key <- Core.recordFieldValue <$> Dhall.Map.lookup "mapKey" kvs+        , Just value <- Core.recordFieldValue <$> Dhall.Map.lookup "mapValue" kvs+            = liftA2 (,) (extract k key) (extract v value)+    extractOut expr = typeError expectedOut expr++    expectedOut = do+        k' <- Core.makeRecordField <$> expected k+        v' <- Core.makeRecordField <$> expected v+        pure $ Record $ Dhall.Map.fromList+            [ ("mapKey", k')+            , ("mapValue", v')]++{-| Decode @()@ from an empty record.++>>> input unit "{=}"  -- GHC doesn't print the result if it is ()++-}+unit :: Decoder ()+unit = Decoder {..}+  where+    extract (RecordLit fields)+        | Data.Foldable.null fields = pure ()+    extract expr = typeError expected expr++    expected = pure $ Record mempty++{-| Decode 'Void' from an empty union.++Since @<>@ is uninhabited, @'Dhall.input' 'void'@ will always fail.+-}+void :: Decoder Void+void = union mempty++{-| Decode a `String`++>>> input string "\"ABC\""+"ABC"++-}+string :: Decoder String+string = Data.Text.Lazy.unpack <$> lazyText++{-| Given a pair of `Decoder`s, decode a tuple-record into their pairing.++>>> input (pair natural bool) "{ _1 = 42, _2 = False }"+(42,False)+-}+pair :: Decoder a -> Decoder b -> Decoder (a, b)+pair l r = Decoder extractOut expectedOut+  where+    extractOut expr@(RecordLit fields) =+      (,) <$> Data.Maybe.maybe (typeError expectedOut expr) (extract l)+                (Core.recordFieldValue <$> Dhall.Map.lookup "_1" fields)+          <*> Data.Maybe.maybe (typeError expectedOut expr) (extract r)+                (Core.recordFieldValue <$> Dhall.Map.lookup "_2" fields)+    extractOut expr = typeError expectedOut expr++    expectedOut = do+        l' <- Core.makeRecordField <$> expected l+        r' <- Core.makeRecordField <$> expected r+        pure $ Record $ Dhall.Map.fromList+            [ ("_1", l')+            , ("_2", r')]++++{-| The 'RecordDecoder' applicative functor allows you to build a 'Decoder'+    from a Dhall record.++    For example, let's take the following Haskell data type:++>>> :{+data Project = Project+  { projectName :: Text+  , projectDescription :: Text+  , projectStars :: Natural+  }+:}++    And assume that we have the following Dhall record that we would like to+    parse as a @Project@:++> { name =+>     "dhall-haskell"+> , description =+>     "A configuration language guaranteed to terminate"+> , stars =+>     289+> }++    Our decoder has type 'Decoder' @Project@, but we can't build that out of any+    smaller decoders, as 'Decoder's cannot be combined (they are only 'Functor's).+    However, we can use a 'RecordDecoder' to build a 'Decoder' for @Project@:++>>> :{+project :: Decoder Project+project =+  record+    ( Project <$> field "name" strictText+              <*> field "description" strictText+              <*> field "stars" natural+    )+:}+-}+newtype RecordDecoder a =+  RecordDecoder+    ( Data.Functor.Product.Product+        ( Control.Applicative.Const+            (Dhall.Map.Map Text (Expector (Expr Src Void)))+        )+        ( Data.Functor.Compose.Compose ((->) (Expr Src Void)) (Extractor Src Void)+        )+        a+    )+  deriving (Functor, Applicative)++-- | Run a 'RecordDecoder' to build a 'Decoder'.+record :: RecordDecoder a -> Dhall.Marshal.Decode.Decoder a+record+    (RecordDecoder+        (Data.Functor.Product.Pair+            (Control.Applicative.Const fields)+            (Data.Functor.Compose.Compose extract)+        )+    ) = Decoder {..}+  where+    expected = Record <$> traverse (fmap Core.makeRecordField) fields++-- | Parse a single field of a record.+field :: Text -> Decoder a -> RecordDecoder a+field key (Decoder {..}) =+  RecordDecoder+    ( Data.Functor.Product.Pair+        ( Control.Applicative.Const+            (Dhall.Map.singleton key expected)+        )+        ( Data.Functor.Compose.Compose extractBody )+    )+  where+    extractBody expr@(RecordLit fields) = case Core.recordFieldValue <$> Dhall.Map.lookup key fields of+      Just v -> extract v+      _      -> typeError expected expr+    extractBody expr = typeError expected expr++++{-| The 'UnionDecoder' monoid allows you to build a 'Decoder' from a Dhall union.++    For example, let's take the following Haskell data type:++>>> :{+data Status = Queued Natural+            | Result Text+            | Errored Text+:}++    And assume that we have the following Dhall union that we would like to+    parse as a @Status@:++> < Result : Text+> | Queued : Natural+> | Errored : Text+> >.Result "Finish successfully"++    Our decoder has type 'Decoder' @Status@, but we can't build that out of any+    smaller decoders, as 'Decoder's cannot be combined (they are only 'Functor's).+    However, we can use a 'UnionDecoder' to build a 'Decoder' for @Status@:++>>> :{+status :: Decoder Status+status = union+  (  ( Queued  <$> constructor "Queued"  natural )+  <> ( Result  <$> constructor "Result"  strictText )+  <> ( Errored <$> constructor "Errored" strictText )+  )+:}++-}+newtype UnionDecoder a =+    UnionDecoder+      ( Data.Functor.Compose.Compose (Dhall.Map.Map Text) Decoder a )+  deriving (Functor)++instance Semigroup (UnionDecoder a) where+    (<>) = coerce ((<>) :: Dhall.Map.Map Text (Decoder a) -> Dhall.Map.Map Text (Decoder a) -> Dhall.Map.Map Text (Decoder a))++instance Monoid (UnionDecoder a) where+    mempty = coerce (mempty :: Dhall.Map.Map Text (Decoder a))++-- | Run a 'UnionDecoder' to build a 'Decoder'.+union :: UnionDecoder a -> Decoder a+union (UnionDecoder (Data.Functor.Compose.Compose mp)) = Decoder {..}+  where+    extract expr = case expected' of+        Failure e -> Failure $ fmap ExpectedTypeError e+        Success x -> extract' expr x++    extract' e0 mp' = Data.Maybe.maybe (typeError expected e0) (uncurry Dhall.Marshal.Decode.extract) $ do+        (fld, e1, rest) <- extractUnionConstructor e0++        t <- Dhall.Map.lookup fld mp++        guard $+            Core.Union rest `Core.judgmentallyEqual` Core.Union (Dhall.Map.delete fld mp')++        pure (t, e1)++    expected = Union <$> expected'++    expected' = traverse (fmap notEmptyRecord . Dhall.Marshal.Decode.expected) mp++-- | Parse a single constructor of a union.+constructor :: Text -> Decoder a -> UnionDecoder a+constructor key valueDecoder = UnionDecoder+    ( Data.Functor.Compose.Compose (Dhall.Map.singleton key valueDecoder) )++++{-| A newtype suitable for collecting one or more errors.+-}+newtype DhallErrors e = DhallErrors+   { getErrors :: NonEmpty e+   } deriving (Eq, Functor, Semigroup)++instance (Show (DhallErrors e), Typeable e) => Exception (DhallErrors e)++{-| Render a given prefix and some errors to a string.+-}+showDhallErrors :: Show e => String -> DhallErrors e -> String+showDhallErrors _   (DhallErrors (e :| [])) = show e+showDhallErrors ctx (DhallErrors es) = prefix <> (unlines . Data.List.NonEmpty.toList . fmap show $ es)+  where+    prefix =+        "Multiple errors were encountered" ++ ctx ++ ": \n\+        \                                               \n"++{-| One or more errors returned from extracting a Dhall expression to a+    Haskell expression.+-}+type ExtractErrors s a = DhallErrors (ExtractError s a)++instance (Pretty s, Pretty a, Typeable s, Typeable a) => Show (ExtractErrors s a) where+    show = showDhallErrors " during extraction"++{-| Extraction of a value can fail for two reasons, either a type mismatch (which should not happen,+    as expressions are type-checked against the expected type before being passed to @extract@), or+    a term-level error, described with a freeform text value.+-}+data ExtractError s a =+    TypeMismatch (InvalidDecoder s a)+  | ExpectedTypeError ExpectedTypeError+  | ExtractError Text+  deriving (Eq)++instance (Pretty s, Pretty a, Typeable s, Typeable a) => Show (ExtractError s a) where+  show (TypeMismatch e)      = show e+  show (ExpectedTypeError e) = show e+  show (ExtractError es)     = unlines+      [ _ERROR <> ": Failed extraction                                                   "+      , "                                                                                "+      , "The expression type-checked successfully but the transformation to the target   "+      , "type failed with the following error:                                           "+      , "                                                                                "+      , Data.Text.unpack es+      , "                                                                                "+      ]++instance (Pretty s, Pretty a, Typeable s, Typeable a) => Exception (ExtractError s a)++{-| Useful synonym for the `Validation` type used when marshalling Dhall+    expressions.+-}+type Extractor s a = Validation (ExtractErrors s a)++{-| Generate a type error during extraction by specifying the expected type+    and the actual type.+    The expected type is not yet determined.+-}+typeError :: Expector (Expr s a) -> Expr s a -> Extractor s a b+typeError expected actual = Failure $ case expected of+    Failure e         -> fmap ExpectedTypeError e+    Success expected' -> DhallErrors $ pure $ TypeMismatch $ InvalidDecoder expected' actual++-- | Turn a `Data.Text.Text` message into an extraction failure.+extractError :: Text -> Extractor s a b+extractError = Failure . DhallErrors . pure . ExtractError++{-| Useful synonym for the equivalent `Either` type used when marshalling Dhall+    code.+-}+type MonadicExtractor s a = Either (ExtractErrors s a)++-- | Switches from an @Applicative@ extraction result, able to accumulate errors,+-- to a @Monad@ extraction result, able to chain sequential operations.+toMonadic :: Extractor s a b -> MonadicExtractor s a b+toMonadic = validationToEither++-- | Switches from a @Monad@ extraction result, able to chain sequential errors,+-- to an @Applicative@ extraction result, able to accumulate errors.+fromMonadic :: MonadicExtractor s a b -> Extractor s a b+fromMonadic = eitherToValidation++{-| 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 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+  , invalidDecoderExpression :: Expr s a+  }+  deriving (Eq, Typeable)++instance (Pretty s, Typeable s, Pretty a, Typeable a) => Exception (InvalidDecoder s a)++instance (Pretty s, Pretty a, Typeable s, Typeable a) => Show (InvalidDecoder s a) where+    show InvalidDecoder { .. } = unlines+        [ _ERROR <> ": Invalid Dhall.Decoder                                               "+        , "                                                                                "+        , "Every Decoder must provide an extract function that does not fail with a type   "+        , "error if an expression matches the expected type.  You provided a Decoder that  "+        , "disobeys this contract                                                          "+        , "                                                                                "+        , "The Decoder provided has the expected dhall type:                               "+        , "                                                                                "+        , show (Dhall.Util.insert invalidDecoderExpected)+        , "                                                                                "+        , "and it threw a type error during extraction from the well-typed expression:     "+        , "                                                                                "+        , show (Dhall.Util.insert invalidDecoderExpression)+        , "                                                                                "+        ]++{-| Useful synonym for the `Validation` type used when marshalling Dhall+    expressions.+-}+type Expector = Validation ExpectedTypeErrors++{-| One or more errors returned when determining the Dhall type of a+    Haskell expression.+-}+type ExpectedTypeErrors = DhallErrors ExpectedTypeError++{-| Error type used when determining the Dhall type of a Haskell expression.+-}+data ExpectedTypeError = RecursiveTypeError+    deriving (Eq, Show)++instance Exception ExpectedTypeError++instance Show ExpectedTypeErrors where+    show = showDhallErrors " while determining the expected type"++_ERROR :: String+_ERROR = "\ESC[1;31mError\ESC[0m"
+ src/Dhall/Marshal/Encode.hs view
@@ -0,0 +1,1068 @@+{-# LANGUAGE ConstraintKinds            #-}+{-# LANGUAGE DefaultSignatures          #-}+{-# LANGUAGE FlexibleContexts           #-}+{-# LANGUAGE FlexibleInstances          #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE OverloadedStrings          #-}+{-# LANGUAGE RankNTypes                 #-}+{-# LANGUAGE RecordWildCards            #-}+{-# LANGUAGE ScopedTypeVariables        #-}+{-# LANGUAGE TupleSections              #-}+{-# LANGUAGE TypeApplications           #-}+{-# LANGUAGE TypeOperators              #-}+{-# LANGUAGE UndecidableInstances       #-}++{-| Please read the "Dhall.Tutorial" module, which contains a tutorial explaining+    how to use the language, the compiler, and this library+-}++module Dhall.Marshal.Encode+    ( -- * General+      Encoder(..)+    , ToDhall(..)+    , Inject+    , inject++      -- * Building encoders++      -- ** Records+    , RecordEncoder(..)+    , recordEncoder+    , encodeField+    , encodeFieldWith+      -- ** Unions+    , UnionEncoder(..)+    , unionEncoder+    , encodeConstructor+    , encodeConstructorWith+    , (>|<)++      -- * Generic encoding+    , GenericToDhall(..)+    , genericToDhall+    , genericToDhallWith+    , genericToDhallWithInputNormalizer+    , InterpretOptions(..)+    , SingletonConstructors(..)+    , defaultInterpretOptions++      -- * Miscellaneous+    , InputNormalizer(..)+    , defaultInputNormalizer+    , Result+    , (>$<)+    , (>*<)++    -- * Re-exports+    , Natural+    , Seq+    , Text+    , Vector+    , Generic+    ) where++import Control.Monad.Trans.State.Strict+import Data.Functor.Contravariant           (Contravariant (..), Op (..), (>$<))+import Data.Functor.Contravariant.Divisible (Divisible (..), divided)+import Dhall.Parser                         (Src (..))+import Dhall.Syntax+    ( Chunks (..)+    , DhallDouble (..)+    , Expr (..)+    )+import GHC.Generics+import Prelude                              hiding (maybe, sequence)++import qualified Control.Applicative+import qualified Data.ByteString+import qualified Data.ByteString.Lazy+import qualified Data.ByteString.Short+import qualified Data.Functor.Product+import qualified Data.HashMap.Strict   as HashMap+import qualified Data.HashSet+import qualified Data.Map+import qualified Data.Scientific+import qualified Data.Sequence+import qualified Data.Set+import qualified Data.Text+import qualified Data.Text.Lazy+import qualified Data.Text.Short+import qualified Data.Time             as Time+import qualified Data.Vector+import qualified Data.Void+import qualified Dhall.Core            as Core+import qualified Dhall.Map++import Dhall.Marshal.Internal++-- $setup+-- >>> :set -XRecordWildCards+-- >>> import Dhall.Pretty.Internal (prettyExpr)++{-| An @(Encoder a)@ represents a way to marshal a value of type @\'a\'@ from+    Haskell into Dhall.+-}+data Encoder a = Encoder+    { embed    :: a -> Expr Src Void+    -- ^ Embeds a Haskell value as a Dhall expression+    , declared :: Expr Src Void+    -- ^ Dhall type of the Haskell value+    }++instance Contravariant Encoder where+    contramap f (Encoder embed declared) = Encoder embed' declared+      where+        embed' x = embed (f x)++{-| This class is used by `Dhall.Marshal.Decode.FromDhall` instance for functions:++> instance (ToDhall a, FromDhall b) => FromDhall (a -> b)++    You can convert Dhall functions with "simple" inputs (i.e. instances of this+    class) into Haskell functions.  This works by:++    * Marshaling the input to the Haskell function into a Dhall expression (i.e.+      @x :: Expr Src Void@)+    * Applying the Dhall function (i.e. @f :: Expr Src Void@) to the Dhall input+      (i.e. @App f x@)+    * Normalizing the syntax tree (i.e. @normalize (App f x)@)+    * Marshaling the resulting Dhall expression back into a Haskell value++    This class auto-generates a default implementation for types that+    implement `Generic`.  This does not auto-generate an instance for recursive+    types.++    The default instance can be tweaked using 'genericToDhallWith'/'genericToDhallWithInputNormalizer'+    and custom 'InterpretOptions', or using+    [DerivingVia](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-DerivingVia)+    and 'Dhall.Deriving.Codec' from "Dhall.Deriving".+-}+class ToDhall a where+    injectWith :: InputNormalizer -> Encoder a+    default injectWith+        :: (Generic a, GenericToDhall (Rep a)) => InputNormalizer -> Encoder a+    injectWith _ = genericToDhall++-- | A compatibility alias for `ToDhall`+type Inject = ToDhall+{-# DEPRECATED Inject "Use ToDhall instead" #-}++{-| Use the default input normalizer for injecting a value.++> inject = injectWith defaultInputNormalizer+-}+inject :: ToDhall a => Encoder a+inject = injectWith defaultInputNormalizer++++instance ToDhall Void where+    injectWith _ = Encoder {..}+      where+        embed = Data.Void.absurd++        declared = Union mempty++instance ToDhall Bool where+    injectWith _ = Encoder {..}+      where+        embed = BoolLit++        declared = Bool++instance ToDhall Data.ByteString.Short.ShortByteString where+    injectWith options =+        contramap Data.ByteString.Short.fromShort (injectWith options)++instance ToDhall Data.ByteString.Lazy.ByteString where+    injectWith options =+        contramap Data.ByteString.Lazy.toStrict (injectWith options)++instance ToDhall Data.ByteString.ByteString where+    injectWith _ = Encoder {..}+      where+        embed bytes = BytesLit bytes++        declared = Bytes++instance ToDhall Data.Text.Short.ShortText where+    injectWith _ = Encoder {..}+      where+        embed text =+            TextLit (Chunks [] (Data.Text.Short.toText text))++        declared = Text++instance ToDhall Data.Text.Lazy.Text where+    injectWith _ = Encoder {..}+      where+        embed text =+            TextLit (Chunks [] (Data.Text.Lazy.toStrict text))++        declared = Text++instance ToDhall Text where+    injectWith _ = Encoder {..}+      where+        embed text = TextLit (Chunks [] text)++        declared = Text++instance {-# OVERLAPS #-} ToDhall String where+    injectWith inputNormalizer =+        contramap Data.Text.pack (injectWith inputNormalizer :: Encoder Text)++instance ToDhall Natural where+    injectWith _ = Encoder {..}+      where+        embed = NaturalLit++        declared = Natural++instance ToDhall Integer where+    injectWith _ = Encoder {..}+      where+        embed = IntegerLit++        declared = Integer++instance ToDhall Int where+    injectWith _ = Encoder {..}+      where+        embed = IntegerLit . toInteger++        declared = Integer++instance ToDhall Int8 where+    injectWith _ = Encoder {..}+      where+        embed = IntegerLit . toInteger++        declared = Integer++instance ToDhall Int16 where+    injectWith _ = Encoder {..}+      where+        embed = IntegerLit . toInteger++        declared = Integer++instance ToDhall Int32 where+    injectWith _ = Encoder {..}+      where+        embed = IntegerLit . toInteger++        declared = Integer++instance ToDhall Int64 where+    injectWith _ = Encoder {..}+      where+        embed = IntegerLit . toInteger++        declared = Integer++{-| Encode a 'Word' to a Dhall @Natural@.++>>> embed inject (12 :: Word)+NaturalLit 12+-}+instance ToDhall Word where+    injectWith _ = Encoder {..}+      where+        embed = NaturalLit . fromIntegral++        declared = Natural++{-| Encode a 'Word8' to a Dhall @Natural@.++>>> embed inject (12 :: Word8)+NaturalLit 12+-}+instance ToDhall Word8 where+    injectWith _ = Encoder {..}+      where+        embed = NaturalLit . fromIntegral++        declared = Natural++{-| Encode a 'Word16' to a Dhall @Natural@.++>>> embed inject (12 :: Word16)+NaturalLit 12+-}+instance ToDhall Word16 where+    injectWith _ = Encoder {..}+      where+        embed = NaturalLit . fromIntegral++        declared = Natural++{-| Encode a 'Word32' to a Dhall @Natural@.++>>> embed inject (12 :: Word32)+NaturalLit 12+-}+instance ToDhall Word32 where+    injectWith _ = Encoder {..}+      where+        embed = NaturalLit . fromIntegral++        declared = Natural++{-| Encode a 'Word64' to a Dhall @Natural@.++>>> embed inject (12 :: Word64)+NaturalLit 12+-}+instance ToDhall Word64 where+    injectWith _ = Encoder {..}+      where+        embed = NaturalLit . fromIntegral++        declared = Natural++instance ToDhall Double where+    injectWith _ = Encoder {..}+      where+        embed = DoubleLit . DhallDouble++        declared = Double++instance ToDhall Scientific where+    injectWith inputNormalizer =+        contramap Data.Scientific.toRealFloat (injectWith inputNormalizer :: Encoder Double)++instance ToDhall () where+    injectWith _ = Encoder {..}+      where+        embed = const (RecordLit mempty)++        declared = Record mempty++instance ToDhall a => ToDhall (Maybe a) where+    injectWith inputNormalizer = Encoder embedOut declaredOut+      where+        embedOut (Just x ) = Some (embedIn x)+        embedOut  Nothing  = App None declaredIn++        Encoder embedIn declaredIn = injectWith inputNormalizer++        declaredOut = App Optional declaredIn++instance ToDhall a => ToDhall (Seq a) where+    injectWith inputNormalizer = Encoder embedOut declaredOut+      where+        embedOut xs = ListLit listType (fmap embedIn xs)+          where+            listType+                | null xs   = Just (App List declaredIn)+                | otherwise = Nothing++        declaredOut = App List declaredIn++        Encoder embedIn declaredIn = injectWith inputNormalizer++instance ToDhall a => ToDhall [a] where+    injectWith = fmap (contramap Data.Sequence.fromList) injectWith++instance ToDhall a => ToDhall (Vector a) where+    injectWith = fmap (contramap Data.Vector.toList) injectWith++instance ToDhall Time.TimeOfDay where+    injectWith _ = Encoder {..}+      where+        embed timeOfDay = TimeLiteral timeOfDay 12++        declared = Time++instance ToDhall Time.Day where+    injectWith _ = Encoder {..}+      where+        embed = DateLiteral++        declared = Date++instance ToDhall Time.TimeZone where+    injectWith _ = Encoder {..}+      where+        embed = TimeZoneLiteral++        declared = TimeZone++instance ToDhall Time.LocalTime where+    injectWith _ = recordEncoder $+      adapt+        >$< encodeField "date"+        >*< encodeField "time"+      where+        adapt (Time.LocalTime date time) = (date, time)++instance ToDhall Time.ZonedTime where+    injectWith _ = recordEncoder $+      adapt+        >$< encodeField "date"+        >*< encodeField "time"+        >*< encodeField "timeZone"+      where+        adapt (Time.ZonedTime (Time.LocalTime date time) timeZone) = (date, (time, timeZone))++instance ToDhall Time.UTCTime where+    injectWith = contramap (Time.utcToZonedTime Time.utc) . injectWith++instance ToDhall Time.DayOfWeek where+    injectWith _ = Encoder{..}+      where+        embed Time.Sunday =+            Field declared (Core.makeFieldSelection "Sunday")+        embed Time.Monday =+            Field declared (Core.makeFieldSelection "Monday" )+        embed Time.Tuesday =+            Field declared (Core.makeFieldSelection "Tuesday")+        embed Time.Wednesday =+            Field declared (Core.makeFieldSelection "Wednesday")+        embed Time.Thursday =+            Field declared (Core.makeFieldSelection "Thursday")+        embed Time.Friday =+            Field declared (Core.makeFieldSelection "Friday")+        embed Time.Saturday =+            Field declared (Core.makeFieldSelection "Saturday")++        declared =+            Union+                (Dhall.Map.fromList+                    [ ("Sunday", Nothing)+                    , ("Monday", Nothing)+                    , ("Tuesday", Nothing)+                    , ("Wednesday", Nothing)+                    , ("Thursday", Nothing)+                    , ("Friday", Nothing)+                    , ("Saturday", Nothing)+                    ]+                )++{-| Note that the output list will be sorted.++>>> let x = Data.Set.fromList ["mom", "hi" :: Text]+>>> prettyExpr $ embed inject x+[ "hi", "mom" ]++-}+instance ToDhall a => ToDhall (Data.Set.Set a) where+    injectWith = fmap (contramap Data.Set.toAscList) injectWith++-- | Note that the output list may not be sorted+instance ToDhall a => ToDhall (Data.HashSet.HashSet a) where+    injectWith = fmap (contramap Data.HashSet.toList) injectWith++instance (ToDhall a, ToDhall b) => ToDhall (a, b)++{-| Embed a `Data.Map` as a @Prelude.Map.Type@.++>>> prettyExpr $ embed inject (Data.Map.fromList [(1 :: Natural, True)])+[ { mapKey = 1, mapValue = True } ]++>>> prettyExpr $ embed inject (Data.Map.fromList [] :: Data.Map.Map Natural Bool)+[] : List { mapKey : Natural, mapValue : Bool }++-}+instance (ToDhall k, ToDhall v) => ToDhall (Data.Map.Map k v) where+    injectWith inputNormalizer = Encoder embedOut declaredOut+      where+        embedOut m = ListLit listType (mapEntries m)+          where+            listType+                | Data.Map.null m = Just declaredOut+                | otherwise       = Nothing++        declaredOut = App List (Record $ Dhall.Map.fromList+                          [ ("mapKey", Core.makeRecordField declaredK)+                          , ("mapValue", Core.makeRecordField declaredV)+                          ])++        mapEntries = Data.Sequence.fromList . fmap recordPair . Data.Map.toList+        recordPair (k, v) = RecordLit $ Dhall.Map.fromList+                                [ ("mapKey", Core.makeRecordField $ embedK k)+                                , ("mapValue", Core.makeRecordField $ embedV v)+                                ]++        Encoder embedK declaredK = injectWith inputNormalizer+        Encoder embedV declaredV = injectWith inputNormalizer++{-| Embed a `Data.HashMap` as a @Prelude.Map.Type@.++>>> prettyExpr $ embed inject (HashMap.fromList [(1 :: Natural, True)])+[ { mapKey = 1, mapValue = True } ]++>>> prettyExpr $ embed inject (HashMap.fromList [] :: HashMap Natural Bool)+[] : List { mapKey : Natural, mapValue : Bool }++-}+instance (ToDhall k, ToDhall v) => ToDhall (HashMap k v) where+    injectWith inputNormalizer = Encoder embedOut declaredOut+      where+        embedOut m = ListLit listType (mapEntries m)+          where+            listType+                | HashMap.null m = Just declaredOut+                | otherwise       = Nothing++        declaredOut = App List (Record $ Dhall.Map.fromList+                          [ ("mapKey", Core.makeRecordField declaredK)+                          , ("mapValue", Core.makeRecordField declaredV)+                          ])++        mapEntries = Data.Sequence.fromList . fmap recordPair . HashMap.toList+        recordPair (k, v) = RecordLit $ Dhall.Map.fromList+                                [ ("mapKey", Core.makeRecordField $ embedK k)+                                , ("mapValue", Core.makeRecordField $ embedV v)+                                ]++        Encoder embedK declaredK = injectWith inputNormalizer+        Encoder embedV declaredV = injectWith inputNormalizer++instance ToDhall (f (Result f)) => ToDhall (Result f) where+    injectWith inputNormalizer = Encoder {..}+      where+        embed = App "Make" . Dhall.Marshal.Encode.embed (injectWith inputNormalizer) . _unResult+        declared = "result"++instance forall f. (Functor f, ToDhall (f (Result f))) => ToDhall (Fix f) where+    injectWith inputNormalizer = Encoder {..}+      where+        embed fixf =+          Lam Nothing (Core.makeFunctionBinding "result" (Const Core.Type)) $+            Lam Nothing (Core.makeFunctionBinding "Make" makeType) $+              embed' . fixToResult $ fixf++        declared = Pi Nothing "result" (Const Core.Type) $ Pi Nothing "_" makeType "result"++        makeType = Pi Nothing "_" declared' "result"+        Encoder embed' _ = injectWith @(Dhall.Marshal.Internal.Result f) inputNormalizer+        Encoder _ declared' = injectWith @(f (Dhall.Marshal.Internal.Result f)) inputNormalizer++fixToResult :: Functor f => Fix f -> Result f+fixToResult (Fix x) = Result (fmap fixToResult x)++++{-| This is the underlying class that powers the `Dhall.Marshal.Decode.FromDhall` class's support+    for automatically deriving a generic implementation.+-}+class GenericToDhall f where+    genericToDhallWithNormalizer :: InputNormalizer -> InterpretOptions -> State Int (Encoder (f a))++instance GenericToDhall f => GenericToDhall (M1 D d f) where+    genericToDhallWithNormalizer inputNormalizer options = do+        res <- genericToDhallWithNormalizer inputNormalizer options+        pure (contramap unM1 res)++instance GenericToDhall f => GenericToDhall (M1 C c f) where+    genericToDhallWithNormalizer inputNormalizer options = do+        res <- genericToDhallWithNormalizer inputNormalizer options+        pure (contramap unM1 res)++instance (Selector s, ToDhall a) => GenericToDhall (M1 S s (K1 i a)) where+    genericToDhallWithNormalizer inputNormalizer InterpretOptions{..} = do+        let Encoder { embed = embed', declared = declared' } =+                injectWith inputNormalizer++        let n :: M1 S s (K1 i a) r+            n = undefined++        name <- fieldModifier <$> getSelName n++        let embed0 (M1 (K1 x)) = embed' x++        let embed1 (M1 (K1 x)) =+                RecordLit (Dhall.Map.singleton name (Core.makeRecordField $ embed' x))++        let embed =+                case singletonConstructors of+                    Bare                    -> embed0+                    Smart | selName n == "" -> embed0+                    _                       -> embed1++        let declared =+                case singletonConstructors of+                    Bare ->+                        declared'+                    Smart | selName n == "" ->+                        declared'+                    _ ->+                        Record (Dhall.Map.singleton name $ Core.makeRecordField declared')++        return (Encoder {..})++instance (Constructor c1, Constructor c2, GenericToDhall f1, GenericToDhall f2) => GenericToDhall (M1 C c1 f1 :+: M1 C c2 f2) where+    genericToDhallWithNormalizer inputNormalizer options@(InterpretOptions {..}) = pure (Encoder {..})+      where+        embed (L1 (M1 l)) =+            case notEmptyRecordLit (embedL l) of+                Nothing ->+                    Field declared $ Core.makeFieldSelection keyL+                Just valL ->+                    App (Field declared $ Core.makeFieldSelection keyL) valL++        embed (R1 (M1 r)) =+            case notEmptyRecordLit (embedR r) of+                Nothing ->+                    Field declared $ Core.makeFieldSelection keyR+                Just valR ->+                    App (Field declared $ Core.makeFieldSelection keyR) valR++        declared =+            Union+                (Dhall.Map.fromList+                    [ (keyL, notEmptyRecord declaredL)+                    , (keyR, notEmptyRecord declaredR)+                    ]+                )++        nL :: M1 i c1 f1 a+        nL = undefined++        nR :: M1 i c2 f2 a+        nR = undefined++        keyL = constructorModifier (Data.Text.pack (conName nL))+        keyR = constructorModifier (Data.Text.pack (conName nR))++        Encoder embedL declaredL = evalState (genericToDhallWithNormalizer inputNormalizer options) 1+        Encoder embedR declaredR = evalState (genericToDhallWithNormalizer inputNormalizer options) 1++instance (Constructor c, GenericToDhall (f :+: g), GenericToDhall h) => GenericToDhall ((f :+: g) :+: M1 C c h) where+    genericToDhallWithNormalizer inputNormalizer options@(InterpretOptions {..}) = pure (Encoder {..})+      where+        embed (L1 l) =+            case maybeValL of+                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 $ Core.makeFieldSelection keyR+                Just valR -> App (Field declared $ Core.makeFieldSelection keyR) valR++        nR :: M1 i c h a+        nR = undefined++        keyR = constructorModifier (Data.Text.pack (conName nR))++        declared = Union (Dhall.Map.insert keyR (notEmptyRecord declaredR) ktsL)++        Encoder embedL declaredL = evalState (genericToDhallWithNormalizer inputNormalizer options) 1+        Encoder embedR declaredR = evalState (genericToDhallWithNormalizer inputNormalizer options) 1++        ktsL = unsafeExpectUnion "genericToDhallWithNormalizer (:+:)" declaredL++instance (Constructor c, GenericToDhall f, GenericToDhall (g :+: h)) => GenericToDhall (M1 C c f :+: (g :+: h)) where+    genericToDhallWithNormalizer inputNormalizer options@(InterpretOptions {..}) = pure (Encoder {..})+      where+        embed (L1 (M1 l)) =+            case notEmptyRecordLit (embedL l) of+                Nothing   -> Field declared $ Core.makeFieldSelection keyL+                Just valL -> App (Field declared $ Core.makeFieldSelection keyL) valL+        embed (R1 r) =+            case maybeValR of+                Nothing   -> Field declared $ Core.makeFieldSelection keyR+                Just valR -> App (Field declared $ Core.makeFieldSelection keyR) valR+          where+            (keyR, maybeValR) =+                unsafeExpectUnionLit "genericToDhallWithNormalizer (:+:)" (embedR r)++        nL :: M1 i c f a+        nL = undefined++        keyL = constructorModifier (Data.Text.pack (conName nL))++        declared = Union (Dhall.Map.insert keyL (notEmptyRecord declaredL) ktsR)++        Encoder embedL declaredL = evalState (genericToDhallWithNormalizer inputNormalizer options) 1+        Encoder embedR declaredR = evalState (genericToDhallWithNormalizer inputNormalizer options) 1++        ktsR = unsafeExpectUnion "genericToDhallWithNormalizer (:+:)" declaredR++instance (GenericToDhall (f :+: g), GenericToDhall (h :+: i)) => GenericToDhall ((f :+: g) :+: (h :+: i)) where+    genericToDhallWithNormalizer inputNormalizer options = pure (Encoder {..})+      where+        embed (L1 l) =+            case maybeValL of+                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 $ Core.makeFieldSelection keyR+                Just valR -> App (Field declared $ Core.makeFieldSelection keyR) valR+          where+            (keyR, maybeValR) =+                unsafeExpectUnionLit "genericToDhallWithNormalizer (:+:)" (embedR r)++        declared = Union (Dhall.Map.union ktsL ktsR)++        Encoder embedL declaredL = evalState (genericToDhallWithNormalizer inputNormalizer options) 1+        Encoder embedR declaredR = evalState (genericToDhallWithNormalizer inputNormalizer options) 1++        ktsL = unsafeExpectUnion "genericToDhallWithNormalizer (:+:)" declaredL+        ktsR = unsafeExpectUnion "genericToDhallWithNormalizer (:+:)" declaredR++instance (GenericToDhall (f :*: g), GenericToDhall (h :*: i)) => GenericToDhall ((f :*: g) :*: (h :*: i)) where+    genericToDhallWithNormalizer inputNormalizer options = do+        Encoder embedL declaredL <- genericToDhallWithNormalizer inputNormalizer options+        Encoder embedR declaredR <- genericToDhallWithNormalizer inputNormalizer options++        let embed (l :*: r) =+                RecordLit (Dhall.Map.union mapL mapR)+              where+                mapL =+                    unsafeExpectRecordLit "genericToDhallWithNormalizer (:*:)" (embedL l)++                mapR =+                    unsafeExpectRecordLit "genericToDhallWithNormalizer (:*:)" (embedR r)++        let declared = Record (Dhall.Map.union mapL mapR)+              where+                mapL = unsafeExpectRecord "genericToDhallWithNormalizer (:*:)" declaredL+                mapR = unsafeExpectRecord "genericToDhallWithNormalizer (:*:)" declaredR++        pure (Encoder {..})++instance (GenericToDhall (f :*: g), Selector s, ToDhall a) => GenericToDhall ((f :*: g) :*: M1 S s (K1 i a)) where+    genericToDhallWithNormalizer inputNormalizer options@InterpretOptions{..} = do+        let nR :: M1 S s (K1 i a) r+            nR = undefined++        nameR <- fmap fieldModifier (getSelName nR)++        Encoder embedL declaredL <- genericToDhallWithNormalizer inputNormalizer options++        let Encoder embedR declaredR = injectWith inputNormalizer++        let embed (l :*: M1 (K1 r)) =+                RecordLit (Dhall.Map.insert nameR (Core.makeRecordField $ embedR r) mapL)+              where+                mapL =+                    unsafeExpectRecordLit "genericToDhallWithNormalizer (:*:)" (embedL l)++        let declared = Record (Dhall.Map.insert nameR (Core.makeRecordField declaredR) mapL)+              where+                mapL = unsafeExpectRecord "genericToDhallWithNormalizer (:*:)" declaredL++        return (Encoder {..})++instance (Selector s, ToDhall a, GenericToDhall (f :*: g)) => GenericToDhall (M1 S s (K1 i a) :*: (f :*: g)) where+    genericToDhallWithNormalizer inputNormalizer options@InterpretOptions{..} = do+        let nL :: M1 S s (K1 i a) r+            nL = undefined++        nameL <- fmap fieldModifier (getSelName nL)++        let Encoder embedL declaredL = injectWith inputNormalizer++        Encoder embedR declaredR <- genericToDhallWithNormalizer inputNormalizer options++        let embed (M1 (K1 l) :*: r) =+                RecordLit (Dhall.Map.insert nameL (Core.makeRecordField $ embedL l) mapR)+              where+                mapR =+                    unsafeExpectRecordLit "genericToDhallWithNormalizer (:*:)" (embedR r)++        let declared = Record (Dhall.Map.insert nameL (Core.makeRecordField declaredL) mapR)+              where+                mapR = unsafeExpectRecord "genericToDhallWithNormalizer (:*:)" declaredR++        return (Encoder {..})++instance (Selector s1, Selector s2, ToDhall a1, ToDhall a2) => GenericToDhall (M1 S s1 (K1 i1 a1) :*: M1 S s2 (K1 i2 a2)) where+    genericToDhallWithNormalizer inputNormalizer InterpretOptions{..} = do+        let nL :: M1 S s1 (K1 i1 a1) r+            nL = undefined++        let nR :: M1 S s2 (K1 i2 a2) r+            nR = undefined++        nameL <- fmap fieldModifier (getSelName nL)+        nameR <- fmap fieldModifier (getSelName nR)++        let Encoder embedL declaredL = injectWith inputNormalizer+        let Encoder embedR declaredR = injectWith inputNormalizer++        let embed (M1 (K1 l) :*: M1 (K1 r)) =+                RecordLit $+                    Dhall.Map.fromList+                        [ (nameL, Core.makeRecordField $ embedL l)+                        , (nameR, Core.makeRecordField $ embedR r) ]+++        let declared =+                Record $ Dhall.Map.fromList+                    [ (nameL, Core.makeRecordField declaredL)+                    , (nameR, Core.makeRecordField declaredR) ]+++        return (Encoder {..})++instance GenericToDhall U1 where+    genericToDhallWithNormalizer _ _ = pure (Encoder {..})+      where+        embed _ = RecordLit mempty++        declared = Record mempty++{-| Use the default options for injecting a value, whose structure is+determined generically.++This can be used when you want to use 'ToDhall' on types that you don't+want to define orphan instances for.+-}+genericToDhall+  :: (Generic a, GenericToDhall (Rep a)) => Encoder a+genericToDhall+    = genericToDhallWith defaultInterpretOptions++{-| Use custom options for injecting a value, whose structure is+determined generically.++This can be used when you want to use 'ToDhall' on types that you don't+want to define orphan instances for.+-}+genericToDhallWith+  :: (Generic a, GenericToDhall (Rep a)) => InterpretOptions -> Encoder a+genericToDhallWith options = genericToDhallWithInputNormalizer options defaultInputNormalizer++{-| `genericToDhallWithInputNormalizer` is like `genericToDhallWith`, but+    instead of using the `defaultInputNormalizer` it expects an custom+    `InputNormalizer`.+-}+genericToDhallWithInputNormalizer+  :: (Generic a, GenericToDhall (Rep a)) => InterpretOptions -> InputNormalizer -> Encoder a+genericToDhallWithInputNormalizer options inputNormalizer+    = contramap GHC.Generics.from (evalState (genericToDhallWithNormalizer inputNormalizer options) 1)++++{-| The 'RecordEncoder' divisible (contravariant) functor allows you to build+    an 'Encoder' for a Dhall record.++    For example, let's take the following Haskell data type:++>>> :{+data Project = Project+  { projectName :: Text+  , projectDescription :: Text+  , projectStars :: Natural+  }+:}++    And assume that we have the following Dhall record that we would like to+    parse as a @Project@:++> { name =+>     "dhall-haskell"+> , description =+>     "A configuration language guaranteed to terminate"+> , stars =+>     289+> }++    Our encoder has type 'Encoder' @Project@, but we can't build that out of any+    smaller encoders, as 'Encoder's cannot be combined (they are only 'Contravariant's).+    However, we can use an 'RecordEncoder' to build an 'Encoder' for @Project@:++>>> :{+injectProject :: Encoder Project+injectProject =+  recordEncoder+    ( adapt >$< encodeFieldWith "name" inject+            >*< encodeFieldWith "description" inject+            >*< encodeFieldWith "stars" inject+    )+  where+    adapt (Project{..}) = (projectName, (projectDescription, projectStars))+:}++    Or, since we are simply using the `ToDhall` instance to inject each field, we could write++>>> :{+injectProject :: Encoder Project+injectProject =+  recordEncoder+    ( adapt >$< encodeField "name"+            >*< encodeField "description"+            >*< encodeField "stars"+    )+  where+    adapt (Project{..}) = (projectName, (projectDescription, projectStars))+:}++-}+newtype RecordEncoder a+  = RecordEncoder (Dhall.Map.Map Text (Encoder a))++instance Contravariant RecordEncoder where+  contramap f (RecordEncoder encodeTypeRecord) = RecordEncoder $ contramap f <$> encodeTypeRecord++instance Divisible RecordEncoder where+  divide f (RecordEncoder bEncoderRecord) (RecordEncoder cEncoderRecord) =+      RecordEncoder+    $ Dhall.Map.union+      ((contramap $ fst . f) <$> bEncoderRecord)+      ((contramap $ snd . f) <$> cEncoderRecord)+  conquer = RecordEncoder mempty++-- | Convert a `RecordEncoder` into the equivalent `Encoder`.+recordEncoder :: RecordEncoder a -> Encoder a+recordEncoder (RecordEncoder encodeTypeRecord) = Encoder makeRecordLit recordType+  where+    recordType = Record $ (Core.makeRecordField . declared) <$> encodeTypeRecord+    makeRecordLit x = RecordLit $ (Core.makeRecordField . ($ x) . embed) <$> encodeTypeRecord++{-| Specify how to encode one field of a record using the default `ToDhall`+    instance for that type.+-}+encodeField :: ToDhall a => Text -> RecordEncoder a+encodeField name = encodeFieldWith name inject++{-| Specify how to encode one field of a record by supplying an explicit+    `Encoder` for that field.+-}+encodeFieldWith :: Text -> Encoder a -> RecordEncoder a+encodeFieldWith name encodeType = RecordEncoder $ Dhall.Map.singleton name encodeType++++{-| 'UnionEncoder' allows you to build an 'Encoder' for a Dhall record.++    For example, let's take the following Haskell data type:++>>> :{+data Status = Queued Natural+            | Result Text+            | Errored Text+:}++    And assume that we have the following Dhall union that we would like to+    parse as a @Status@:++> < Result : Text+> | Queued : Natural+> | Errored : Text+> >.Result "Finish successfully"++    Our encoder has type 'Encoder' @Status@, but we can't build that out of any+    smaller encoders, as 'Encoder's cannot be combined.+    However, we can use an 'UnionEncoder' to build an 'Encoder' for @Status@:++>>> :{+injectStatus :: Encoder Status+injectStatus = adapt >$< unionEncoder+  (   encodeConstructorWith "Queued"  inject+  >|< encodeConstructorWith "Result"  inject+  >|< encodeConstructorWith "Errored" inject+  )+  where+    adapt (Queued  n) = Left n+    adapt (Result  t) = Right (Left t)+    adapt (Errored e) = Right (Right e)+:}++    Or, since we are simply using the `ToDhall` instance to inject each branch, we could write++>>> :{+injectStatus :: Encoder Status+injectStatus = adapt >$< unionEncoder+  (   encodeConstructor "Queued"+  >|< encodeConstructor "Result"+  >|< encodeConstructor "Errored"+  )+  where+    adapt (Queued  n) = Left n+    adapt (Result  t) = Right (Left t)+    adapt (Errored e) = Right (Right e)+:}++-}+newtype UnionEncoder a =+  UnionEncoder+    ( Data.Functor.Product.Product+        ( Control.Applicative.Const+            ( Dhall.Map.Map+                Text+                ( Expr Src Void )+            )+        )+        ( Op (Text, Expr Src Void) )+        a+    )+  deriving (Contravariant)++-- | Convert a `UnionEncoder` into the equivalent `Encoder`.+unionEncoder :: UnionEncoder a -> Encoder a+unionEncoder ( UnionEncoder ( Data.Functor.Product.Pair ( Control.Applicative.Const fields ) ( Op embedF ) ) ) =+    Encoder+      { embed = \x ->+          let (name, y) = embedF x+          in  case notEmptyRecordLit y of+                  Nothing  -> Field (Union fields') $ Core.makeFieldSelection name+                  Just val -> App (Field (Union fields') $ Core.makeFieldSelection name) val+      , declared =+          Union fields'+      }+  where+    fields' = fmap notEmptyRecord fields++{-| Specify how to encode an alternative by using the default `ToDhall` instance+    for that type.+-}+encodeConstructor+    :: ToDhall a+    => Text+    -> UnionEncoder a+encodeConstructor name = encodeConstructorWith name inject++{-| Specify how to encode an alternative by providing an explicit `Encoder`+    for that alternative.+-}+encodeConstructorWith+    :: Text+    -> Encoder a+    -> UnionEncoder a+encodeConstructorWith name encodeType = UnionEncoder $+    Data.Functor.Product.Pair+      ( Control.Applicative.Const+          ( Dhall.Map.singleton+              name+              ( declared encodeType )+          )+      )+      ( Op ( (name,) . embed encodeType )+      )++-- | Combines two 'UnionEncoder' values.  See 'UnionEncoder' for usage+-- notes.+--+-- Ideally, this matches 'Data.Functor.Contravariant.Divisible.chosen';+-- however, this allows 'UnionEncoder' to not need a 'Divisible' instance+-- itself (since no instance is possible).+(>|<) :: UnionEncoder a -> UnionEncoder b -> UnionEncoder (Either a b)+UnionEncoder (Data.Functor.Product.Pair (Control.Applicative.Const mx) (Op fx))+    >|< UnionEncoder (Data.Functor.Product.Pair (Control.Applicative.Const my) (Op fy)) =+    UnionEncoder+      ( Data.Functor.Product.Pair+          ( Control.Applicative.Const (mx <> my) )+          ( Op (either fx fy) )+      )++infixr 5 >|<++++-- | Infix 'divided'+(>*<) :: Divisible f => f a -> f b -> f (a, b)+(>*<) = divided++infixr 5 >*<
+ src/Dhall/Marshal/Internal.hs view
@@ -0,0 +1,193 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ViewPatterns      #-}++{-| Please read the "Dhall.Tutorial" module, which contains a tutorial explaining+    how to use the language, the compiler, and this library+-}++module Dhall.Marshal.Internal+    ( InputNormalizer(..)+    , defaultInputNormalizer+    , InterpretOptions(..)+    , SingletonConstructors(..)+    , defaultInterpretOptions++    -- * Miscellaneous+    , Result(..)++    -- * Helpers for the generic deriving machinery+    , getSelName+    , notEmptyRecord+    , notEmptyRecordLit+    , unsafeExpectRecord+    , unsafeExpectRecordLit+    , unsafeExpectUnion+    , unsafeExpectUnionLit++    -- * Re-exports+    , Fix(..)+    , HashMap+    , Int8+    , Int16+    , Int32+    , Int64+    , Map+    , Natural+    , Scientific+    , Seq+    , Text+    , Vector+    , Void+    , Word8+    , Word16+    , Word32+    , Word64+    , Generic+    ) where++import Control.Monad.Trans.State.Strict+import Data.Fix                         (Fix (..))+import Data.HashMap.Strict              (HashMap)+import Data.Int                         (Int16, Int32, Int64, Int8)+import Data.Map                         (Map)+import Data.Scientific                  (Scientific)+import Data.Sequence                    (Seq)+import Data.Text                        (Text)+import Data.Vector                      (Vector)+import Data.Void                        (Void)+import Data.Word                        (Word16, Word32, Word64, Word8)+import Dhall.Parser                     (Src (..))+import Dhall.Syntax                     (Expr (..), RecordField (..))+import GHC.Generics+import Numeric.Natural                  (Natural)+import Prelude                          hiding (maybe, sequence)++import qualified Data.Text+import qualified Dhall.Core as Core+import qualified Dhall.Map++{-| This type is exactly the same as `Data.Fix.Fix` except with a different+    `Dhall.Marshal.Decode.FromDhall` instance.  This intermediate type+    simplifies the implementation of the inner loop for the+    `Dhall.Marshal.Decode.FromDhall` instance for `Fix`.+-}+newtype Result f = Result { _unResult :: f (Result f) }++{-| Use these options to tweak how Dhall derives a generic implementation of+    `Dhall.Marshal.Decode.FromDhall`.+-}+data InterpretOptions = InterpretOptions+    { fieldModifier       :: Text -> Text+    -- ^ Function used to transform Haskell field names into their corresponding+    --   Dhall field names+    , constructorModifier :: Text -> Text+    -- ^ Function used to transform Haskell constructor names into their+    --   corresponding Dhall alternative names+    , singletonConstructors :: SingletonConstructors+    -- ^ Specify how to handle constructors with only one field.  The default is+    --   `Smart`+    }++{-| This is only used by the `Dhall.Marshal.Decode.FromDhall` instance for+    functions in order to normalize the function input before marshaling the+    input into a Dhall expression.+-}+newtype InputNormalizer = InputNormalizer+  { getInputNormalizer :: Core.ReifiedNormalizer Void }++-- | Default normalization-related settings (no custom normalization)+defaultInputNormalizer :: InputNormalizer+defaultInputNormalizer = InputNormalizer+ { getInputNormalizer = Core.ReifiedNormalizer (const (pure Nothing)) }++{-| This type specifies how to model a Haskell constructor with 1 field in+    Dhall++    For example, consider the following Haskell datatype definition:++    > data Example = Foo { x :: Double } | Bar Double++    Depending on which option you pick, the corresponding Dhall type could be:++    > < Foo : Double | Bar : Double >                   -- Bare++    > < Foo : { x : Double } | Bar : { _1 : Double } >  -- Wrapped++    > < Foo : { x : Double } | Bar : Double >           -- Smart+-}+data SingletonConstructors+    = Bare+    -- ^ Never wrap the field in a record+    | Wrapped+    -- ^ Always wrap the field in a record+    | Smart+    -- ^ Only fields in a record if they are named++{-| Default interpret options for generics-based instances,+    which you can tweak or override, like this:++> genericAutoWith+>     (defaultInterpretOptions { fieldModifier = Data.Text.Lazy.dropWhile (== '_') })+-}+defaultInterpretOptions :: InterpretOptions+defaultInterpretOptions = InterpretOptions+    { fieldModifier =+          id+    , constructorModifier =+          id+    , singletonConstructors =+          Smart+    }++unsafeExpectUnion+    :: Text -> Expr Src Void -> Dhall.Map.Map Text (Maybe (Expr Src Void))+unsafeExpectUnion _ (Union kts) =+    kts+unsafeExpectUnion name expression =+    Core.internalError+        (name <> ": Unexpected constructor: " <> Core.pretty expression)++unsafeExpectRecord+    :: Text -> Expr Src Void -> Dhall.Map.Map Text (RecordField Src Void)+unsafeExpectRecord _ (Record kts) =+    kts+unsafeExpectRecord name expression =+    Core.internalError+        (name <> ": Unexpected constructor: " <> Core.pretty expression)++unsafeExpectUnionLit+    :: Text+    -> Expr Src Void+    -> (Text, Maybe (Expr Src Void))+unsafeExpectUnionLit _ (Field (Union _) (Core.fieldSelectionLabel -> k)) =+    (k, Nothing)+unsafeExpectUnionLit _ (App (Field (Union _) (Core.fieldSelectionLabel -> k)) v) =+    (k, Just v)+unsafeExpectUnionLit name expression =+    Core.internalError+        (name <> ": Unexpected constructor: " <> Core.pretty expression)++unsafeExpectRecordLit+    :: Text -> Expr Src Void -> Dhall.Map.Map Text (RecordField Src Void)+unsafeExpectRecordLit _ (RecordLit kvs) =+    kvs+unsafeExpectRecordLit name expression =+    Core.internalError+        (name <> ": Unexpected constructor: " <> Core.pretty expression)++notEmptyRecordLit :: Expr s a -> Maybe (Expr s a)+notEmptyRecordLit e = case e of+    RecordLit m | null m -> Nothing+    _                    -> Just e++notEmptyRecord :: Expr s a -> Maybe (Expr s a)+notEmptyRecord e = case e of+    Record m | null m -> Nothing+    _                 -> Just e++getSelName :: Selector s => M1 i s f a -> State Int Text+getSelName n = case selName n of+    "" -> do i <- get+             put (i + 1)+             pure (Data.Text.pack ("_" ++ show i))+    nn -> pure (Data.Text.pack nn)
src/Dhall/Normalize.hs view
@@ -23,7 +23,7 @@ import Control.Applicative   (empty) import Data.Foldable import Data.Functor.Identity (Identity (..))-import Data.List.NonEmpty    (NonEmpty(..))+import Data.List.NonEmpty    (NonEmpty (..)) import Data.Sequence         (ViewL (..), ViewR (..)) import Data.Traversable import Instances.TH.Lift     ()@@ -39,6 +39,7 @@     , PreferAnnotation (..)     , RecordField (..)     , Var (..)+    , WithComponent (..)     )  import qualified Data.Sequence@@ -46,9 +47,8 @@ import qualified Data.Text     as Text import qualified Dhall.Eval    as Eval import qualified Dhall.Map-import qualified Dhall.Set import qualified Dhall.Syntax  as Syntax-import qualified Lens.Family   as Lens+import qualified Lens.Micro    as Lens  {-| Returns `True` if two expressions are α-equivalent and β-equivalent and     `False` otherwise@@ -66,13 +66,13 @@ -} subst :: Var -> Expr s a -> Expr s a -> Expr s a subst _ _ (Const a) = Const a-subst (V x n) e (Lam (FunctionBinding src0 y src1 src2 _A) b) =-    Lam (FunctionBinding src0 y src1 src2 _A') b'+subst (V x n) e (Lam cs (FunctionBinding src0 y src1 src2 _A) b) =+    Lam cs (FunctionBinding src0 y src1 src2 _A') b'   where     _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'+subst (V x n) e (Pi cs y _A _B) = Pi cs y _A' _B'   where     _A' = subst (V x n )                         e  _A     _B' = subst (V x n') (Syntax.shift 1 (V y 0) e) _B@@ -115,8 +115,8 @@     using De Bruijn indices to distinguish them  >>> 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)))))+>>> alphaNormalize (Lam mempty (mfb "a" (Const Type)) (Lam mempty (mfb "b" (Const Type)) (Lam mempty (mfb "x" "a") (Lam mempty (mfb "y" "b") "x"))))+Lam Nothing (FunctionBinding {functionBindingSrc0 = Nothing, functionBindingVariable = "_", functionBindingSrc1 = Nothing, functionBindingSrc2 = Nothing, functionBindingAnnotation = Const Type}) (Lam Nothing (FunctionBinding {functionBindingSrc0 = Nothing, functionBindingVariable = "_", functionBindingSrc1 = Nothing, functionBindingSrc2 = Nothing, functionBindingAnnotation = Const Type}) (Lam Nothing (FunctionBinding {functionBindingSrc0 = Nothing, functionBindingVariable = "_", functionBindingSrc1 = Nothing, functionBindingSrc2 = Nothing, functionBindingAnnotation = Var (V "_" 1)}) (Lam Nothing (FunctionBinding {functionBindingSrc0 = Nothing, functionBindingVariable = "_", functionBindingSrc1 = Nothing, functionBindingSrc2 = Nothing, functionBindingAnnotation = Var (V "_" 1)}) (Var (V "_" 1)))))      α-normalization does not affect free variables: @@ -161,6 +161,7 @@ normalizeWith :: Eq a => Maybe (ReifiedNormalizer a) -> Expr s a -> Expr t a normalizeWith (Just ctx) t = runIdentity (normalizeWithM (getReifiedNormalizer ctx) t) normalizeWith _          t = Eval.normalize t+{-# INLINABLE normalizeWith #-}  {-| This function generalizes `normalizeWith` by allowing the custom normalizer     to use an arbitrary `Monad`@@ -172,27 +173,25 @@     :: (Monad m, Eq a) => NormalizerM m a -> Expr s a -> m (Expr t a) normalizeWithM ctx e0 = loop (Syntax.denote e0)  where- loop =  \case-    Const k -> pure (Const k)-    Var v -> pure (Var v)-    Lam (FunctionBinding { functionBindingVariable = x, functionBindingAnnotation = _A }) b ->-        Lam <$> (Syntax.makeFunctionBinding x <$> _A') <*> b'-      where-        _A' = loop _A-        b'  = loop b-    Pi x _A _B -> Pi x <$> _A' <*> _B'-      where-        _A' = loop _A-        _B' = loop _B-    App f a -> do-      res <- ctx (App f a)-      case res of-          Just e1 -> loop e1-          Nothing -> do+  loop e = ctx e >>= \case+      Just e' -> loop e'+      Nothing -> case e of+          Const k -> pure (Const k)+          Var v -> pure (Var v)+          Lam cs (FunctionBinding { functionBindingVariable = x, functionBindingAnnotation = _A }) b ->+              Lam cs <$> (Syntax.makeFunctionBinding x <$> _A') <*> b'+            where+              _A' = loop _A+              b'  = loop b+          Pi cs x _A _B -> Pi cs x <$> _A' <*> _B'+            where+              _A' = loop _A+              _B' = loop _B+          App f a -> do               f' <- loop f               a' <- loop a               case f' of-                Lam (FunctionBinding _ x _ _ _A) b₀ -> do+                Lam _ (FunctionBinding _ x _ _ _A) b₀ -> do                      let a₂ = Syntax.shift 1 (V x 0) a'                     let b₁ = subst (V x 0) a₂ b₀@@ -212,14 +211,22 @@                         strict =       strictLoop (fromIntegral n0 :: Integer)                         lazy   = loop (  lazyLoop (fromIntegral n0 :: Integer)) -                        strictLoop 0 = loop zero-                        strictLoop !n = App succ' <$> strictLoop (n - 1) >>= loop+                        strictLoop !n = do+                            z <- loop zero+                            strictLoopShortcut n z +                        strictLoopShortcut 0 !previous = pure previous+                        strictLoopShortcut !n !previous = do+                            current <- loop (App succ' previous)+                            if judgmentallyEqual previous current+                                then pure previous+                                else strictLoopShortcut (n - 1) current+                         lazyLoop 0 = zero                         lazyLoop !n = App succ' (lazyLoop (n - 1))                     App NaturalBuild g -> loop (App (App (App g Natural) succ) zero)                       where-                        succ = Lam (Syntax.makeFunctionBinding "n" Natural) (NaturalPlus "n" (NaturalLit 1))+                        succ = Lam mempty (Syntax.makeFunctionBinding "n" Natural) (NaturalPlus "n" (NaturalLit 1))                          zero = NaturalLit 0                     App NaturalIsZero (NaturalLit n) -> pure (BoolLit (n == 0))@@ -261,8 +268,8 @@                         list = App List _A₀                          cons =-                            Lam (Syntax.makeFunctionBinding "a" _A₀)-                                (Lam+                            Lam mempty (Syntax.makeFunctionBinding "a" _A₀)+                                (Lam mempty                                     (Syntax.makeFunctionBinding "as" (App List _A₁))                                     (ListAppend (ListLit Nothing (pure "a")) "as")                                 )@@ -376,326 +383,382 @@                                                 suffix                                      loop (TextAppend (TextLit (Chunks [(prefix, replacement)] "")) (App (App (App TextReplace (TextLit (Chunks [] needleText))) replacement) (TextLit (Chunks ((remainder, firstInterpolation) : chunks) lastText))))+                    App DateShow (DateLiteral date) ->+                        loop (TextLit (Chunks [] text))+                      where+                        text = Eval.dateShow date+                    App TimeShow (TimeLiteral time precision) ->+                        loop (TextLit (Chunks [] text))+                      where+                        text = Eval.timeShow time precision+                    App TimeZoneShow (TimeZoneLiteral timezone) ->+                        loop (TextLit (Chunks [] text))+                      where+                        text = Eval.timezoneShow timezone                     _ -> do                         res2 <- ctx (App f' a')                         case res2 of                             Nothing -> pure (App f' a')                             Just app' -> loop app'-    Let (Binding _ f _ _ _ r) b -> loop b''-      where-        r'  = Syntax.shift   1  (V f 0) r-        b'  = subst (V f 0) r' b-        b'' = Syntax.shift (-1) (V f 0) b'-    Annot x _ -> loop x-    Bool -> pure Bool-    BoolLit b -> pure (BoolLit b)-    BoolAnd x y -> decide <$> loop x <*> loop y-      where-        decide (BoolLit True )  r              = r-        decide (BoolLit False)  _              = BoolLit False-        decide  l              (BoolLit True ) = l-        decide  _              (BoolLit False) = BoolLit False-        decide  l               r-            | Eval.judgmentallyEqual l r = l-            | otherwise                  = BoolAnd l r-    BoolOr x y -> decide <$> loop x <*> loop y-      where-        decide (BoolLit False)  r              = r-        decide (BoolLit True )  _              = BoolLit True-        decide  l              (BoolLit False) = l-        decide  _              (BoolLit True ) = BoolLit True-        decide  l               r-            | Eval.judgmentallyEqual l r = l-            | otherwise                  = BoolOr l r-    BoolEQ x y -> decide <$> loop x <*> loop y-      where-        decide (BoolLit True )  r              = r-        decide  l              (BoolLit True ) = l-        decide  l               r-            | Eval.judgmentallyEqual l r = BoolLit True-            | otherwise                  = BoolEQ l r-    BoolNE x y -> decide <$> loop x <*> loop y-      where-        decide (BoolLit False)  r              = r-        decide  l              (BoolLit False) = l-        decide  l               r-            | Eval.judgmentallyEqual l r = BoolLit False-            | otherwise                  = BoolNE l r-    BoolIf bool true false -> decide <$> loop bool <*> loop true <*> loop false-      where-        decide (BoolLit True )  l              _              = l-        decide (BoolLit False)  _              r              = r-        decide  b              (BoolLit True) (BoolLit False) = b-        decide  b               l              r-            | Eval.judgmentallyEqual l r = l-            | otherwise                  = BoolIf b l r-    Natural -> pure Natural-    NaturalLit n -> pure (NaturalLit n)-    NaturalFold -> pure NaturalFold-    NaturalBuild -> pure NaturalBuild-    NaturalIsZero -> pure NaturalIsZero-    NaturalEven -> pure NaturalEven-    NaturalOdd -> pure NaturalOdd-    NaturalToInteger -> pure NaturalToInteger-    NaturalShow -> pure NaturalShow-    NaturalSubtract -> pure NaturalSubtract-    NaturalPlus x y -> decide <$> loop x <*> loop y-      where-        decide (NaturalLit 0)  r             = r-        decide  l             (NaturalLit 0) = l-        decide (NaturalLit m) (NaturalLit n) = NaturalLit (m + n)-        decide  l              r             = NaturalPlus l r-    NaturalTimes x y -> decide <$> loop x <*> loop y-      where-        decide (NaturalLit 1)  r             = r-        decide  l             (NaturalLit 1) = l-        decide (NaturalLit 0)  _             = NaturalLit 0-        decide  _             (NaturalLit 0) = NaturalLit 0-        decide (NaturalLit m) (NaturalLit n) = NaturalLit (m * n)-        decide  l              r             = NaturalTimes l r-    Integer -> pure Integer-    IntegerLit n -> pure (IntegerLit n)-    IntegerClamp -> pure IntegerClamp-    IntegerNegate -> pure IntegerNegate-    IntegerShow -> pure IntegerShow-    IntegerToDouble -> pure IntegerToDouble-    Double -> pure Double-    DoubleLit n -> pure (DoubleLit n)-    DoubleShow -> pure DoubleShow-    Text -> pure Text-    TextLit (Chunks xys z) -> do-        chunks' <- mconcat <$> chunks-        case chunks' of-            Chunks [("", x)] "" -> pure x-            c                   -> pure (TextLit c)-      where-        chunks =-          ((++ [Chunks [] z]) . concat) <$> traverse process xys+          Let (Binding _ f _ _ _ r) b -> loop b''+            where+              r'  = Syntax.shift   1  (V f 0) r+              b'  = subst (V f 0) r' b+              b'' = Syntax.shift (-1) (V f 0) b'+          Annot x _ -> loop x+          Bool -> pure Bool+          BoolLit b -> pure (BoolLit b)+          BoolAnd x y -> decide <$> loop x <*> loop y+            where+              decide (BoolLit True )  r              = r+              decide (BoolLit False)  _              = BoolLit False+              decide  l              (BoolLit True ) = l+              decide  _              (BoolLit False) = BoolLit False+              decide  l               r+                  | Eval.judgmentallyEqual l r = l+                  | otherwise                  = BoolAnd l r+          BoolOr x y -> decide <$> loop x <*> loop y+            where+              decide (BoolLit False)  r              = r+              decide (BoolLit True )  _              = BoolLit True+              decide  l              (BoolLit False) = l+              decide  _              (BoolLit True ) = BoolLit True+              decide  l               r+                  | Eval.judgmentallyEqual l r = l+                  | otherwise                  = BoolOr l r+          BoolEQ x y -> decide <$> loop x <*> loop y+            where+              decide (BoolLit True )  r              = r+              decide  l              (BoolLit True ) = l+              decide  l               r+                  | Eval.judgmentallyEqual l r = BoolLit True+                  | otherwise                  = BoolEQ l r+          BoolNE x y -> decide <$> loop x <*> loop y+            where+              decide (BoolLit False)  r              = r+              decide  l              (BoolLit False) = l+              decide  l               r+                  | Eval.judgmentallyEqual l r = BoolLit False+                  | otherwise                  = BoolNE l r+          BoolIf bool true false -> decide <$> loop bool <*> loop true <*> loop false+            where+              decide (BoolLit True )  l              _              = l+              decide (BoolLit False)  _              r              = r+              decide  b              (BoolLit True) (BoolLit False) = b+              decide  b               l              r+                  | Eval.judgmentallyEqual l r = l+                  | otherwise                  = BoolIf b l r+          Bytes -> pure Bytes+          BytesLit b -> pure (BytesLit b)+          Natural -> pure Natural+          NaturalLit n -> pure (NaturalLit n)+          NaturalFold -> pure NaturalFold+          NaturalBuild -> pure NaturalBuild+          NaturalIsZero -> pure NaturalIsZero+          NaturalEven -> pure NaturalEven+          NaturalOdd -> pure NaturalOdd+          NaturalToInteger -> pure NaturalToInteger+          NaturalShow -> pure NaturalShow+          NaturalSubtract -> pure NaturalSubtract+          NaturalPlus x y -> decide <$> loop x <*> loop y+            where+              decide (NaturalLit 0)  r             = r+              decide  l             (NaturalLit 0) = l+              decide (NaturalLit m) (NaturalLit n) = NaturalLit (m + n)+              decide  l              r             = NaturalPlus l r+          NaturalTimes x y -> decide <$> loop x <*> loop y+            where+              decide (NaturalLit 1)  r             = r+              decide  l             (NaturalLit 1) = l+              decide (NaturalLit 0)  _             = NaturalLit 0+              decide  _             (NaturalLit 0) = NaturalLit 0+              decide (NaturalLit m) (NaturalLit n) = NaturalLit (m * n)+              decide  l              r             = NaturalTimes l r+          Integer -> pure Integer+          IntegerLit n -> pure (IntegerLit n)+          IntegerClamp -> pure IntegerClamp+          IntegerNegate -> pure IntegerNegate+          IntegerShow -> pure IntegerShow+          IntegerToDouble -> pure IntegerToDouble+          Double -> pure Double+          DoubleLit n -> pure (DoubleLit n)+          DoubleShow -> pure DoubleShow+          Text -> pure Text+          TextLit (Chunks xys z) -> do+              chunks' <- mconcat <$> chunks+              case chunks' of+                  Chunks [("", x)] "" -> pure x+                  c                   -> pure (TextLit c)+            where+              chunks =+                ((++ [Chunks [] z]) . concat) <$> traverse process xys -        process (x, y) = do-          y' <- loop y-          case y' of-            TextLit c -> pure [Chunks [] x, c]-            _         -> pure [Chunks [(x, y')] mempty]-    TextAppend x y -> loop (TextLit (Chunks [("", x), ("", y)] ""))-    TextReplace -> pure TextReplace-    TextShow -> pure TextShow-    List -> pure List-    ListLit t es-        | Data.Sequence.null es -> ListLit <$> t' <*> pure Data.Sequence.empty-        | otherwise             -> ListLit Nothing <$> es'-      where-        t'  = traverse loop t-        es' = traverse loop es-    ListAppend x y -> decide <$> loop x <*> loop y-      where-        decide (ListLit _ m)  r            | Data.Sequence.null m = r-        decide  l            (ListLit _ n) | Data.Sequence.null n = l-        decide (ListLit t m) (ListLit _ n)                        = ListLit t (m <> n)-        decide  l             r                                   = ListAppend l r-    ListBuild -> pure ListBuild-    ListFold -> pure ListFold-    ListLength -> pure ListLength-    ListHead -> pure ListHead-    ListLast -> pure ListLast-    ListIndexed -> pure ListIndexed-    ListReverse -> pure ListReverse-    Optional -> pure Optional-    Some a -> Some <$> a'-      where-        a' = loop a-    None -> pure None-    Record kts -> Record . Dhall.Map.sort <$> kts'-      where-        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 s1 s2) = (\e -> RecordField s0 e s1 s2) <$> loop expr-        kvs' = traverse f kvs-    Union kts -> Union . Dhall.Map.sort <$> kts'-      where-        kts' = traverse (traverse loop) kts-    Combine mk x y -> decide <$> loop x <*> loop y-      where-        decide (RecordLit m) r | Data.Foldable.null m =-            r-        decide l (RecordLit n) | Data.Foldable.null n =-            l-        decide (RecordLit m) (RecordLit n) =-            RecordLit (Dhall.Map.unionWith f m n)-          where-            f (RecordField _ expr _ _) (RecordField _ expr' _ _) =-              Syntax.makeRecordField $ decide expr expr'-        decide l r =-            Combine mk l r-    CombineTypes x y -> decide <$> loop x <*> loop y-      where-        decide (Record m) r | Data.Foldable.null m =-            r-        decide l (Record n) | Data.Foldable.null n =-            l-        decide (Record m) (Record n) =-            Record (Dhall.Map.unionWith f m n)-          where-            f (RecordField _ expr _ _) (RecordField _ expr' _ _) =-              Syntax.makeRecordField $ decide expr expr'-        decide l r =-            CombineTypes l r-    Prefer _ x y -> decide <$> loop x <*> loop y-      where-        decide (RecordLit m) r | Data.Foldable.null m =-            r-        decide l (RecordLit n) | Data.Foldable.null n =-            l-        decide (RecordLit m) (RecordLit n) =-            RecordLit (Dhall.Map.union n m)-        decide l r | Eval.judgmentallyEqual l r =-            l-        decide l r =-            Prefer PreferFromSource l r-    RecordCompletion x y ->-        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 ->+              process (x, y) = do+                y' <- loop y                 case y' of-                    Field (Union ktsY) (Syntax.fieldSelectionLabel -> kY) ->-                        case Dhall.Map.lookup kY ktsY of-                            Just Nothing ->-                                case recordFieldValue <$> Dhall.Map.lookup kY kvsX of-                                    Just vX -> return vX-                                    Nothing -> Merge x' y' <$> t'-                            _ ->-                                Merge x' y' <$> t'-                    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-                                    Just vX -> loop (App vX vY)-                                    Nothing -> Merge x' y' <$> t'-                            _ ->-                                Merge x' y' <$> t'-                    Some a ->-                        case recordFieldValue <$> Dhall.Map.lookup "Some" kvsX of-                            Just vX -> loop (App vX a)-                            Nothing -> Merge x' y' <$> t'-                    App None _ ->-                        case recordFieldValue <$> Dhall.Map.lookup "None" kvsX of-                            Just vX -> return vX-                            Nothing -> Merge x' y' <$> t'-                    _ -> Merge x' y' <$> t'-            _ -> Merge x' y' <$> t'-      where-        t' = traverse loop t-    ToMap x t        -> do-        x' <- loop x-        t' <- traverse loop t-        case x' of-            RecordLit kvsX -> do-                let entry (key, value) =-                        RecordLit-                            (Dhall.Map.fromList-                                [ ("mapKey"  , Syntax.makeRecordField $ TextLit (Chunks [] key))-                                , ("mapValue", Syntax.makeRecordField value                  )-                                ]-                            )+                  TextLit c -> pure [Chunks [] x, c]+                  _         -> pure [Chunks [(x, y')] mempty]+          TextAppend x y -> loop (TextLit (Chunks [("", x), ("", y)] ""))+          TextReplace -> pure TextReplace+          TextShow -> pure TextShow+          Date -> pure Date+          DateLiteral d -> pure (DateLiteral d)+          DateShow -> pure DateShow+          Time -> pure Time+          TimeLiteral t p -> pure (TimeLiteral t p)+          TimeShow -> pure TimeShow+          TimeZone -> pure TimeZone+          TimeZoneLiteral z -> pure (TimeZoneLiteral z)+          TimeZoneShow -> pure TimeZoneShow+          List -> pure List+          ListLit t es+              | Data.Sequence.null es -> ListLit <$> t' <*> pure Data.Sequence.empty+              | otherwise             -> ListLit Nothing <$> es'+            where+              t'  = traverse loop t+              es' = traverse loop es+          ListAppend x y -> decide <$> loop x <*> loop y+            where+              decide (ListLit _ m)  r            | Data.Sequence.null m = r+              decide  l            (ListLit _ n) | Data.Sequence.null n = l+              decide (ListLit t m) (ListLit _ n)                        = ListLit t (m <> n)+              decide  l             r                                   = ListAppend l r+          ListBuild -> pure ListBuild+          ListFold -> pure ListFold+          ListLength -> pure ListLength+          ListHead -> pure ListHead+          ListLast -> pure ListLast+          ListIndexed -> pure ListIndexed+          ListReverse -> pure ListReverse+          Optional -> pure Optional+          Some a -> Some <$> a'+            where+              a' = loop a+          None -> pure None+          Record kts -> Record . Dhall.Map.sort <$> kts'+            where+              f (RecordField s0 expr s1 s2) = (\expr' -> RecordField s0 expr' s1 s2) <$> loop expr+              kts' = traverse f kts+          RecordLit kvs -> RecordLit . Dhall.Map.sort <$> kvs'+            where+              f (RecordField s0 expr s1 s2) = (\expr' -> RecordField s0 expr' s1 s2) <$> loop expr+              kvs' = traverse f kvs+          Union kts -> Union . Dhall.Map.sort <$> kts'+            where+              kts' = traverse (traverse loop) kts+          Combine cs mk x y -> decide <$> loop x <*> loop y+            where+              decide (RecordLit m) r | Data.Foldable.null m =+                  r+              decide l (RecordLit n) | Data.Foldable.null n =+                  l+              decide (RecordLit m) (RecordLit n) =+                  RecordLit (Dhall.Map.unionWith f m n)+                where+                  f (RecordField _ expr _ _) (RecordField _ expr' _ _) =+                    Syntax.makeRecordField $ decide expr expr'+              decide l r =+                  Combine cs mk l r+          CombineTypes cs x y -> decide <$> loop x <*> loop y+            where+              decide (Record m) r | Data.Foldable.null m =+                  r+              decide l (Record n) | Data.Foldable.null n =+                  l+              decide (Record m) (Record n) =+                  Record (Dhall.Map.unionWith f m n)+                where+                  f (RecordField _ expr _ _) (RecordField _ expr' _ _) =+                    Syntax.makeRecordField $ decide expr expr'+              decide l r =+                  CombineTypes cs l r+          Prefer cs _ x y -> decide <$> loop x <*> loop y+            where+              decide (RecordLit m) r | Data.Foldable.null m =+                  r+              decide l (RecordLit n) | Data.Foldable.null n =+                  l+              decide (RecordLit m) (RecordLit n) =+                  RecordLit (Dhall.Map.union n m)+              decide l r | Eval.judgmentallyEqual l r =+                  l+              decide l r =+                  Prefer cs PreferFromSource l r+          RecordCompletion x y ->+              loop (Annot (Prefer mempty 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) (Syntax.fieldSelectionLabel -> kY) ->+                              case Dhall.Map.lookup kY ktsY of+                                  Just Nothing ->+                                      case recordFieldValue <$> Dhall.Map.lookup kY kvsX of+                                          Just vX -> return vX+                                          Nothing -> Merge x' y' <$> t'+                                  _ ->+                                      Merge x' y' <$> t'+                          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+                                          Just vX -> loop (App vX vY)+                                          Nothing -> Merge x' y' <$> t'+                                  _ ->+                                      Merge x' y' <$> t'+                          Some a ->+                              case recordFieldValue <$> Dhall.Map.lookup "Some" kvsX of+                                  Just vX -> loop (App vX a)+                                  Nothing -> Merge x' y' <$> t'+                          App None _ ->+                              case recordFieldValue <$> Dhall.Map.lookup "None" kvsX of+                                  Just vX -> return vX+                                  Nothing -> Merge x' y' <$> t'+                          _ -> Merge x' y' <$> t'+                  _ -> Merge x' y' <$> t'+            where+              t' = traverse loop t+          ToMap x t        -> do+              x' <- loop x+              t' <- traverse loop t+              case x' of+                  RecordLit kvsX -> do+                      let entry (key, value) =+                              RecordLit+                                  (Dhall.Map.fromList+                                      [ ("mapKey"  , Syntax.makeRecordField $ TextLit (Chunks [] key))+                                      , ("mapValue", Syntax.makeRecordField value                  )+                                      ]+                                  ) -                let keyValues = Data.Sequence.fromList (map entry (Dhall.Map.toList $ recordFieldValue <$> kvsX))+                      let keyValues = Data.Sequence.fromList (map entry (Dhall.Map.toList $ recordFieldValue <$> kvsX)) -                let listType = case t' of-                        Just _ | null keyValues ->-                            t'-                        _ ->-                            Nothing+                      let listType = case t' of+                              Just _ | null keyValues ->+                                  t'+                              _ ->+                                  Nothing -                return (ListLit listType keyValues)-            _ ->-                return (ToMap x' t')-    Field r k@FieldSelection{fieldSelectionLabel = x}        -> do-        let singletonRecordLit v = RecordLit (Dhall.Map.singleton x v)+                      return (ListLit listType keyValues)+                  _ ->+                      return (ToMap x' t')+          ShowConstructor x -> do+              x' <- loop x+              return $ case x' of+                  Field (Union ktsY) (Syntax.fieldSelectionLabel -> kY) ->+                      case Dhall.Map.lookup kY ktsY of+                          Just Nothing -> TextLit (Chunks [] kY)+                          _ -> ShowConstructor x'+                  App (Field (Union ktsY) (Syntax.fieldSelectionLabel -> kY)) _ ->+                      case Dhall.Map.lookup kY ktsY of+                          Just (Just _) -> TextLit (Chunks [] kY)+                          _ -> ShowConstructor x'+                  Some _ ->+                      TextLit (Chunks [] "Some")+                  App None _ ->+                      TextLit (Chunks [] "None")+                  _ -> ShowConstructor x'+          Field r k@FieldSelection{fieldSelectionLabel = x}        -> do+              let singletonRecordLit v = RecordLit (Dhall.Map.singleton x v) -        r' <- loop r-        case r' of-            RecordLit kvs ->-                case Dhall.Map.lookup x kvs of-                    Just v  -> pure $ recordFieldValue v-                    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_) 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 k)-            Combine m (RecordLit kvs) r_ -> case Dhall.Map.lookup x kvs of-                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)) k)-                Nothing -> loop (Field l k)-            _ -> pure (Field r' k)-    Project x (Left fields)-> do-        x' <- loop x-        let fieldsSet = Dhall.Set.toSet fields-        case x' of-            RecordLit kvs ->-                pure (RecordLit (Dhall.Map.restrictKeys kvs fieldsSet))-            Project y _ ->-                loop (Project y (Left fields))-            Prefer _ l (RecordLit rKvs) -> do-                let rKs = Dhall.Map.keysSet rKvs-                let l' = Project l (Left (Dhall.Set.fromSet (Data.Set.difference fieldsSet rKs)))-                let r' = RecordLit (Dhall.Map.restrictKeys rKvs fieldsSet)-                loop (Prefer PreferFromSource l' r')-            _ | null fields -> pure (RecordLit mempty)-              | otherwise   -> pure (Project x' (Left (Dhall.Set.sort fields)))-    Project r (Right e1) -> do-        e2 <- loop e1+              r' <- loop r+              case r' of+                  RecordLit kvs ->+                      case Dhall.Map.lookup x kvs of+                          Just v  -> pure $ recordFieldValue v+                          Nothing -> Field <$> (RecordLit <$> traverse (Syntax.recordFieldExprs loop) kvs) <*> pure k+                  Project r_ _ -> loop (Field r_ k)+                  Prefer cs _ (RecordLit kvs) r_ -> case Dhall.Map.lookup x kvs of+                      Just v -> pure (Field (Prefer cs 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 k)+                  Combine cs m (RecordLit kvs) r_ -> case Dhall.Map.lookup x kvs of+                      Just v -> pure (Field (Combine cs m (singletonRecordLit v) r_) k)+                      Nothing -> loop (Field r_ k)+                  Combine cs m l (RecordLit kvs) -> case Dhall.Map.lookup x kvs of+                      Just v -> pure (Field (Combine cs m l (singletonRecordLit v)) k)+                      Nothing -> loop (Field l k)+                  _ -> pure (Field r' k)+          Project x (Left fields)-> do+              x' <- loop x+              let fieldsSet = Data.Set.fromList fields+              case x' of+                  RecordLit kvs ->+                      pure (RecordLit (Dhall.Map.restrictKeys kvs fieldsSet))+                  Project y _ ->+                      loop (Project y (Left fields))+                  Prefer cs _ l (RecordLit rKvs) -> do+                      let rKs = Dhall.Map.keysSet rKvs+                      let l' = Project l (Left (Data.Set.toList (Data.Set.difference fieldsSet rKs)))+                      let r' = RecordLit (Dhall.Map.restrictKeys rKvs fieldsSet)+                      loop (Prefer cs PreferFromSource l' r')+                  _ | null fields -> pure (RecordLit mempty)+                    | otherwise   -> pure (Project x' (Left (Data.Set.toList (Data.Set.fromList fields))))+          Project r (Right e1) -> do+              e2 <- loop e1 -        case e2 of-            Record kts ->-                loop (Project r (Left (Dhall.Set.fromSet (Dhall.Map.keysSet kts))))-            _ -> do-                r' <- loop r-                pure (Project r' (Right e2))-    Assert t -> do-        t' <- loop t+              case e2 of+                  Record kts ->+                      loop (Project r (Left (Data.Set.toList (Dhall.Map.keysSet kts))))+                  _ -> do+                      r' <- loop r+                      pure (Project r' (Right e2))+          Assert t -> do+              t' <- loop t -        pure (Assert t')-    Equivalent l r -> do-        l' <- loop l-        r' <- loop r+              pure (Assert t')+          Equivalent cs l r -> do+              l' <- loop l+              r' <- loop r -        pure (Equivalent l' r')-    With e ks v -> do-        e' <- loop e-        v' <- loop v+              pure (Equivalent cs l' r')+          With r ks v -> do+              r' <- loop r+              v' <- loop v -        case e' of-            RecordLit kvs ->-                case ks of-                    k :| [] ->-                        return (RecordLit (Dhall.Map.insert k (Syntax.makeRecordField v') kvs))-                    k₀ :| k₁ : ks' -> do-                        let e₁ =-                                case Dhall.Map.lookup k₀ kvs of-                                    Nothing -> RecordLit mempty-                                    Just r  -> Syntax.recordFieldValue r+              case r' of+                  RecordLit kvs ->+                      case ks of+                          WithLabel k :| [] ->+                              return (RecordLit (Dhall.Map.insert k (Syntax.makeRecordField v') kvs))+                          WithLabel k₀ :| k₁ : ks' -> do+                              let e₁ =+                                      case Dhall.Map.lookup k₀ kvs of+                                          Nothing  -> RecordLit mempty+                                          Just val -> Syntax.recordFieldValue val -                        e₂ <- loop (With e₁ (k₁ :| ks') v')+                              e₂ <- loop (With e₁ (k₁ :| ks') v') -                        return (RecordLit (Dhall.Map.insert k₀ (Syntax.makeRecordField e₂) kvs))-            _ ->-                return (With e' ks v')-    Note _ e' -> loop e'-    ImportAlt l _r -> loop l-    Embed a -> pure (Embed a)+                              return (RecordLit (Dhall.Map.insert k₀ (Syntax.makeRecordField e₂) kvs))+                          WithQuestion :| _ -> do+                              return (With r' ks v')+                  Some t ->+                      case ks of+                          WithQuestion :| [] -> do+                              return (Some v')+                          WithQuestion :| k : ks' -> do+                              w <- loop (With t (k :| ks') v)+                              return (Some w)+                          WithLabel _ :| _ ->+                              return (With r' ks v')+                  App None _T ->+                      case ks of+                          WithQuestion :| _ ->+                              return (App None _T)+                          WithLabel _ :| _ ->+                              return (With r' ks v')+                  _ ->+                      return (With r' ks v')+          Note _ e' -> loop e'+          ImportAlt l _r -> loop l+          Embed a -> pure (Embed a)  -- | Use this to wrap you embedded functions (see `normalizeWith`) to make them --   polymorphic enough to be used.@@ -732,17 +795,20 @@     loop e = case e of       Const _ -> True       Var _ -> True-      Lam (FunctionBinding Nothing _ Nothing Nothing a) b -> loop a && loop b-      Lam _ _ -> False-      Pi _ 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           App NaturalEven (NaturalLit _) -> False           App NaturalOdd (NaturalLit _) -> False           App NaturalShow (NaturalLit _) -> False+          App DateShow (DateLiteral _) -> False+          App TimeShow (TimeLiteral _ _) -> False+          App TimeZoneShow (TimeZoneLiteral _) -> False           App (App NaturalSubtract (NaturalLit _)) (NaturalLit _) -> False           App (App NaturalSubtract (NaturalLit 0)) _ -> False           App (App NaturalSubtract _) (NaturalLit 0) -> False@@ -797,6 +863,8 @@           decide (BoolLit _)  _              _              = False           decide  _          (BoolLit True) (BoolLit False) = False           decide  _           l              r              = not (Eval.judgmentallyEqual l r)+      Bytes -> True+      BytesLit _ -> True       Natural -> True       NaturalLit _ -> True       NaturalFold -> True@@ -840,6 +908,15 @@       TextAppend _ _ -> False       TextReplace -> True       TextShow -> True+      Date -> True+      DateLiteral _ -> True+      DateShow -> True+      Time -> True+      TimeLiteral _ _ -> True+      TimeShow -> True+      TimeZone -> True+      TimeZoneLiteral _ -> True+      TimeZoneShow -> True       List -> True       ListLit t es -> all loop t && all loop es       ListAppend x y -> loop x && loop y && decide x y@@ -867,19 +944,19 @@           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+      Combine _ _ x y -> loop x && loop y && decide x y         where           decide (RecordLit m) _ | Data.Foldable.null m = False           decide _ (RecordLit n) | Data.Foldable.null n = False           decide (RecordLit _) (RecordLit _) = False           decide  _ _ = True-      CombineTypes x y -> loop x && loop y && decide x y+      CombineTypes _ x y -> loop x && loop y && decide x y         where           decide (Record m) _ | Data.Foldable.null m = False           decide _ (Record n) | Data.Foldable.null n = False           decide (Record _) (Record _) = False           decide  _ _ = True-      Prefer _ x y -> loop x && loop y && decide x y+      Prefer _ _ x y -> loop x && loop y && decide x y         where           decide (RecordLit m) _ | Data.Foldable.null m = False           decide _ (RecordLit n) | Data.Foldable.null n = False@@ -897,13 +974,25 @@       ToMap x t -> case x of           RecordLit _ -> False           _ -> loop x && all loop t+      ShowConstructor x -> loop x && case x of+          Field (Union kts) (Syntax.fieldSelectionLabel -> k) ->+              case Dhall.Map.lookup k kts of+                  Just Nothing -> False+                  _            -> True+          App (Field (Union kts) (Syntax.fieldSelectionLabel -> k)) _ ->+              case Dhall.Map.lookup k kts of+                  Just (Just _) -> False+                  _             -> True+          Some _ -> False+          App None _ -> False+          _ -> True       Field r (FieldSelection Nothing k Nothing) -> case r of           RecordLit _ -> False           Project _ _ -> False-          Prefer _ (RecordLit m) _ -> Dhall.Map.keys m == [k] && loop r-          Prefer _ _ (RecordLit _) -> False-          Combine _ (RecordLit m) _ -> Dhall.Map.keys m == [k] && loop r-          Combine _ _ (RecordLit m) -> Dhall.Map.keys m == [k] && loop r+          Prefer _ _ (RecordLit m) _ -> Dhall.Map.keys m == [k] && loop r+          Prefer _ _ _ (RecordLit _) -> False+          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 &&@@ -911,13 +1000,13 @@               Left s -> case r of                   RecordLit _ -> False                   Project _ _ -> False-                  Prefer _ _ (RecordLit _) -> False-                  _ -> not (Dhall.Set.null s) && Dhall.Set.isSorted s+                  Prefer _ _ _ (RecordLit _) -> False+                  _ -> not (null s) && Data.Set.toList (Data.Set.fromList s) == s               Right e' -> case e' of                   Record _ -> False                   _ -> loop e'       Assert t -> loop t-      Equivalent l r -> loop l && loop r+      Equivalent _ l r -> loop l && loop r       With{} -> False       Note _ e' -> loop e'       ImportAlt _ _ -> False@@ -929,7 +1018,7 @@ True >>> "x" `freeIn` "y" False->>> "x" `freeIn` Lam (Syntax.makeFunctionBinding "x" (Const Type)) "x"+>>> "x" `freeIn` Lam mempty (Syntax.makeFunctionBinding "x" (Const Type)) "x" False -} freeIn :: Eq a => Var -> Expr s a -> Bool@@ -941,6 +1030,7 @@     denote' = Syntax.denote      strippedExpression = denote' expression+{-# INLINABLE freeIn #-}  {- $setup >>> import Dhall.Syntax (Const(..))
src/Dhall/Optics.hs view
@@ -3,51 +3,83 @@     for convenience -} -module Dhall.Optics-    ( -- * Utilities-      rewriteOf+{-# LANGUAGE RankNTypes #-}++module Dhall.Optics {-# DEPRECATED "Use the definitions from Lens.Micro of the microlens package directly." #-}+    ( Optic+    , Optic'+       -- * Utilities+    , anyOf+    , rewriteOf     , transformOf     , rewriteMOf     , transformMOf     , mapMOf+    , cosmosOf+    , to+    , foldOf     ) where -import Control.Applicative    (WrappedMonad (..))-import Data.Profunctor.Unsafe (( #. ))-import Lens.Family            (ASetter, LensLike, over)+import Control.Applicative        (Const (..), WrappedMonad (..))+import Data.Monoid                (Any (..))+import Lens.Micro                 (ASetter, LensLike, Traversal, SimpleGetter)+import Lens.Micro.Internal        ((#.)) +import qualified Lens.Micro++-- | Identical to @"Control.Lens.Getter".`Control.Lens.Getter.Getting`@+type Getting r s a = (a -> Const r a) -> s -> Const r s++-- | Identical to @"Control.Lens.Type".`Control.Lens.Type.Optic`@+type Optic p f s t a b = p a (f b) -> p s (f t)++-- | Identical to @"Control.Lens.Type".`Control.Lens.Type.Optic'`@+type Optic' p f s a = Optic p f s s a a++-- | Identical to @"Control.Lens".`Control.Lens.anyOf`@+anyOf :: Getting Any s a -> (a -> Bool) -> s -> Bool+anyOf = Lens.Micro.anyOf+{-# INLINE anyOf #-}+ -- | Identical to @"Control.Lens".`Control.Lens.rewriteOf`@ rewriteOf :: ASetter a b a b -> (b -> Maybe a) -> a -> b-rewriteOf l f = go-  where-    go = transformOf l (\x -> maybe x go (f x))+rewriteOf = Lens.Micro.rewriteOf {-# INLINE rewriteOf #-}  -- | Identical to @"Control.Lens".`Control.Lens.transformOf`@ transformOf :: ASetter a b a b -> (b -> b) -> a -> b-transformOf l f = go-  where-    go = f . over l go+transformOf = Lens.Micro.transformOf {-# INLINE transformOf #-}  -- | Identical to @"Control.Lens".`Control.Lens.rewriteMOf`@ rewriteMOf     :: Monad m     => LensLike (WrappedMonad m) a b a b -> (b -> m (Maybe a)) -> a -> m b-rewriteMOf l f = go-  where-    go = transformMOf l (\x -> f x >>= maybe (return x) go)+rewriteMOf = Lens.Micro.rewriteMOf {-# INLINE rewriteMOf #-}  -- | Identical to @"Control.Lens".`Control.Lens.transformMOf`@ transformMOf     :: Monad m => LensLike (WrappedMonad m) a b a b -> (b -> m b) -> a -> m b-transformMOf l f = go-  where-    go t = mapMOf l go t >>= f+transformMOf = Lens.Micro.transformMOf {-# INLINE transformMOf #-}  -- | Identical to @"Control.Lens".`Control.Lens.mapMOf`@ mapMOf :: LensLike (WrappedMonad m) s t a b -> (a -> m b) -> s -> m t-mapMOf l cmd = unwrapMonad #. l (WrapMonad #. cmd)+mapMOf = Lens.Micro.mapMOf {-# INLINE mapMOf #-}++-- | Identical to @"Control.Lens.Plated".`Control.Lens.Plated.cosmosOf`@+cosmosOf :: Traversal s t s t -> Traversal s t s b+cosmosOf = Lens.Micro.cosmosOf+{-# INLINE cosmosOf #-}++-- | Identical to @"Control.Lens.Getter".`Control.Lens.Getter.to`@+to :: (s -> a) -> SimpleGetter s a+to = Lens.Micro.to+{-# INLINE to #-}++-- | Identical to @"Control.Lens.Fold".`Control.Lens.Fold.foldOf`@+foldOf :: Getting a s a -> s -> a+foldOf l = getConst #. l Const+{-# INLINE foldOf #-}
+ src/Dhall/Package.hs view
@@ -0,0 +1,297 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE LambdaCase   #-}+{-# LANGUAGE MultiWayIf   #-}++-- | Create a package.dhall from files and directory contents.++module Dhall.Package+    ( Options+    , defaultOptions+    , characterSet+    , packageFileName+    , packagingMode+    , PackagingMode(..)+    , writePackage+    , getPackagePathAndContent+    , PackageError(..)+    ) where++import           Control.Exception  (Exception, throwIO)+import           Control.Monad+import           Data.List.NonEmpty (NonEmpty (..))+import           Data.Text          (Text)+import qualified Data.Text          as Text+import           Data.Traversable   (for)+import           Dhall.Core+    ( Directory (..)+    , Expr (..)+    , File (..)+    , FilePrefix (..)+    , Import (..)+    , ImportHashed (..)+    , ImportMode (..)+    , ImportType (..)+    , RecordField (..)+    , makeRecordField+    )+import           Dhall.Map          (Map)+import qualified Dhall.Map          as Map+import           Dhall.Pretty       (CharacterSet (..))+import qualified Dhall.Pretty+import           Dhall.Util         (_ERROR, renderExpression)+import           Lens.Micro         (Lens', lens)+import           System.Directory+import           System.FilePath++-- | Options for package creation.+data Options = Options+    { optionsCharacterSet :: CharacterSet+    , optionsPackageFileName :: String+    , optionsPackagingMode :: PackagingMode+    }++-- | The default options used for packaging.+--+-- The default values for the different settings are:+--+--  * The character set used is the one given by 'Dhall.Pretty.defaultCharacterSet'.+--  * The package file name is @package.dhall@.+--  * The packaging mode is 'OnlyThisPackage'.+defaultOptions :: Options+defaultOptions = Options+    { optionsCharacterSet = Dhall.Pretty.defaultCharacterSet+    , optionsPackageFileName = "package.dhall"+    , optionsPackagingMode = OnlyThisPackage+    }++-- | Access the character set used to render the package content.+characterSet :: Lens' Options CharacterSet+characterSet = lens optionsCharacterSet (\s x -> s { optionsCharacterSet = x })++-- | Access the file name used for the package file.+packageFileName :: Lens' Options String+packageFileName =+    lens optionsPackageFileName (\s x -> s { optionsPackageFileName = x })++-- | Access the packaging mode.+-- See the documentation of 'getPackagePathAndContent'.+packagingMode :: Lens' Options PackagingMode+packagingMode =+    lens optionsPackagingMode (\s x -> s { optionsPackagingMode = x })++-- | Whether to recursively create a package for each subdirectory or not.+-- See the documentation of 'getPackagePathAndContent'.+data PackagingMode+    = OnlyThisPackage+    | RecursiveSubpackages++-- | Create a package.dhall from files and directory contents.+-- For a description of how the package file is constructed see+-- 'getPackagePathAndContent'.+writePackage :: Options -> NonEmpty FilePath -> IO ()+writePackage options inputs = do+    (outputPath, expr) <- getPackagePathAndContent options inputs+    renderExpression (optionsCharacterSet options) True (Just outputPath) expr++-- | Get the path and the Dhall expression for a package file.+--+-- The location of the resulting package file is determined by the first path of the second argument:+--+--   * If it is a directory, it is also the output directory and the package+--     file will be placed there.+--+--   * If it is a file, then the directory that file resides in is the output+--     directory and the package file will be placed there.+--+-- All inputs provided as the second argument must be either in the output+-- directory or below it. They are processed depending on whether+-- the path points to a directory or a file:+--+--   * If the path points to a directory, all files with a @.dhall@ extensions+--     in that directory are included in the package.+--+--     If you passed `Recurse` to the this function, then in addition to these+--     files all subdirectories are traversed and a sub-package created for each+--     one. That sub-package will be included in the package too.+--+--   * If the path points to a regular file, it is included in the package+--     unless it is the path of the package file itself.+--+getPackagePathAndContent+    :: Options+    -> NonEmpty FilePath+    -> IO (FilePath, Expr s Import)+getPackagePathAndContent options (path :| paths) = do+    outputDir <- do+        isDirectory <- doesDirectoryExist path+        return $ if isDirectory then path else takeDirectory path+    outputDir' <- addTrailingPathSeparator <$> makeAbsolute (normalise outputDir)++    -- Check if the supplied @dir@ argument points to a filesystem entry below+    -- the output directory and return the path relative to the output directory.+    let checkOutputDir dir = do+            absoluteDir <- addTrailingPathSeparator <$> makeAbsolute (normalise dir)+            let relativeDir = makeRelative outputDir' absoluteDir+            unless (isRelative relativeDir) $+                throwIO $ AmbiguousOutputDirectory outputDir dir+            return relativeDir++    resultMap <- go Map.empty checkOutputDir (path:paths)+    return (outputDir </> outputFn, RecordLit $ Map.sort resultMap)+    where+        go+            :: Map Text (RecordField s Import)+            -> (FilePath -> IO FilePath)+            -> [FilePath]+            -> IO (Map Text (RecordField s Import))+        go !acc _checkOutputDir [] = return acc+        go !acc checkOutputDir (p:ps) = do+            isDirectory <- doesDirectoryExist p+            isFile <- doesFileExist p+            if | isDirectory -> do+                    void $ checkOutputDir p+                    entries <- listDirectory p+                    (dhallFiles, subdirectories) <- foldMap+                        ( \entry -> do+                            let entry' = p </> entry+                            isDirectoryEntry <- doesDirectoryExist entry'+                            return $ if isDirectoryEntry+                                then (mempty, [entry'])+                                else if hasDhallExtension entry+                                    then ([entry'], mempty)+                                    else mempty+                        ) entries+                    subpackages <- case optionsPackagingMode options of+                        RecursiveSubpackages ->+                            for subdirectories $ \subdirectory -> do+                                writePackage options (subdirectory :| [])+                                return (subdirectory </> outputFn)+                        OnlyThisPackage -> return []+                    go acc checkOutputDir (dhallFiles <> subpackages <> ps)+               | isFile -> do+                    dir <- checkOutputDir $ takeDirectory p++                    let p' = normalise $ dir </> takeFileName p++                    let resultMap = if p' == outputFn+                            then Map.empty+                            else filepathToMap outputFn p'++                    acc' <- mergeMaps acc resultMap+                    go acc' checkOutputDir ps+                | otherwise -> throwIO $ InvalidPath p++        hasDhallExtension :: FilePath -> Bool+        hasDhallExtension entry = takeExtension entry == ".dhall"++        outputFn :: String+        outputFn = optionsPackageFileName options++-- | Construct a nested 'Map' from a 'FilePath'.+-- For example, the filepath @some/file/path.dhall@ will result in something+-- similar to the following:+--+-- fromList+--   [ ("some", fromList+--     [ ("file", fromList+--       [ ("path", ./some/file/path.dhall)+--       ])+--     ])+--   ])+--+-- ... where ./some/file/path.dhall is a Dhall import. If the last component+-- equals the value passed in the @outputFn@ argument we produce a slightly+-- different result. Consider for example the Dhall Prelude: We have some+-- sub-packages there like @List/package.dhall@. If we want to construct the+-- top-level @package.dhall@ we want an entry like+--+-- > List = ./List/package.dhall+--+-- in there and not:+--+-- > List = { package = ./List/package.dhall }+--+filepathToMap :: FilePath -> FilePath -> Map Text (RecordField s Import)+filepathToMap outputFn = go [] . splitDirectories+    where+        go acc [] = go acc ["."]+        go !acc [x] =+                    let import_ = Import+                            { importHashed = ImportHashed+                                { hash = Nothing+                                , importType = Local Here File+                                    { directory = Directory acc+                                    , file = Text.pack x+                                    }+                                }+                            , importMode = Code+                            }+            in Map.singleton (Text.pack $ dropExtension x) $ makeRecordField $ Embed import_+        go !acc [x, y] | y == outputFn =+                    let import_ = Import+                            { importHashed = ImportHashed+                                { hash = Nothing+                                , importType = Local Here File+                                    { directory = Directory (Text.pack x : acc)+                                    , file = Text.pack y+                                    }+                                }+                            , importMode = Code+                            }+            in Map.singleton (Text.pack x) $ makeRecordField $ Embed import_+        go !acc (x:xs) = Map.singleton (Text.pack x) $ makeRecordField $ RecordLit $ go (Text.pack x : acc) xs++-- | Merge two 'Map's constructed with 'filepathToMap'.+-- It will throw an error if the arguments are not compatible with each other, e.g.+-- we cannot merge the following two maps:+--+-- > fromList [ ("file", ./file.dhall) ]+-- > fromList [ ("file", fromList [("nested", ./file/nested.dhall)]) ]+--+mergeMaps :: Map Text (RecordField s Import) -> Map Text (RecordField s Import) -> IO (Map Text (RecordField s Import))+mergeMaps x y = do+    let x' = fmap (:| []) x+        y' = fmap (:| []) y+        z = Map.unionWith (<>) x' y'+    for z $ \case+        v@RecordField{recordFieldValue = Embed{}} :| [] -> return v+        vs | Just rs <- traverse extractRecordLit vs -> makeRecordField . RecordLit . Map.sort <$> foldM mergeMaps Map.empty rs+           | otherwise -> throwIO $ IncompatiblePaths $ foldMap extractEmbeds vs+    where+        extractEmbeds :: RecordField s Import -> [Import]+        extractEmbeds RecordField{recordFieldValue = Embed import_} = [import_]+        extractEmbeds RecordField{recordFieldValue = RecordLit xs} = foldMap extractEmbeds xs+        extractEmbeds _ = mempty++        extractRecordLit :: RecordField s Import -> Maybe (Map Text (RecordField s Import))+        extractRecordLit RecordField{recordFieldValue = RecordLit xs} = Just xs+        extractRecordLit _ = Nothing++-- | Exception thrown when creating a package file.+data PackageError+    = AmbiguousOutputDirectory FilePath FilePath+    | IncompatiblePaths [Import]+    | InvalidPath FilePath++instance Exception PackageError++instance Show PackageError where+    show (AmbiguousOutputDirectory dir1 dir2) =+        _ERROR <> ": ❰dhall package❱ failed because the inputs make it impossible to\n\+        \determine the output directory of the package file. You asked to include files\n\+        \from the following directories in the package:\n\+        \\n" <> dir1 <>+        "\n" <> dir2 <>+        "\n\n\+        \Although those paths might point to the same location they are not lexically the\n\+        \same."++    show (IncompatiblePaths imports) =+        _ERROR <> ": ❰dhall package❱ failed because some inputs are not compatible with\n\+        \each other:\n\+        \\n" <> unlines (map (show . Dhall.Pretty.prettyExpr . Embed) imports)++    show (InvalidPath fp) =+        _ERROR <> ": ❰dhall package❱ failed because the input does not exist or is\n\+        \neither a directory nor a regular file:\n\+        \\n" <> fp
src/Dhall/Parser.hs view
@@ -1,5 +1,5 @@-{-# LANGUAGE RecordWildCards   #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards   #-}  -- | This module contains Dhall's parsing logic @@ -21,12 +21,13 @@     , Parser(..)     ) where -import Control.Exception (Exception)-import Data.Text         (Text)-import Data.Void         (Void)-import Dhall.Src         (Src (..))+import Control.Applicative (many)+import Control.Exception   (Exception)+import Data.Text           (Text)+import Data.Void           (Void)+import Dhall.Src           (Src (..)) import Dhall.Syntax-import Text.Megaparsec   (ParseErrorBundle (..), PosState (..))+import Text.Megaparsec     (ParseErrorBundle (..), PosState (..))  import qualified Data.Text       as Text import qualified Dhall.Core      as Core@@ -123,7 +124,7 @@     Right (txt, r) -> Right (createHeader txt, r)   where     parser = do-        (bytes, _) <- Text.Megaparsec.match whitespace+        (bytes, _) <- Text.Megaparsec.match (many shebang *> whitespace)         r <- expr         Text.Megaparsec.eof         return (bytes, r)
src/Dhall/Parser/Combinators.hs view
@@ -17,33 +17,30 @@     , satisfy     , Dhall.Parser.Combinators.takeWhile     , takeWhile1-    , noDuplicates     , toMap     , toMapWith+    , base     ) where  -import Control.Applicative       (Alternative (..), liftA2)-import Control.Exception         (Exception)-import Control.Monad             (MonadPlus (..))-import Data.String               (IsString (..))-import Data.Text                 (Text)-import Data.Text.Prettyprint.Doc (Pretty (..))-import Data.Void                 (Void)-import Dhall.Map                 (Map)-import Dhall.Set                 (Set)-import Dhall.Src                 (Src (..))-import Text.Parser.Combinators   (try, (<?>))-import Text.Parser.Token         (TokenParsing (..))+import Control.Applicative     (Alternative (..), liftA2)+import Control.Exception       (Exception)+import Control.Monad           (MonadPlus (..))+import Data.String             (IsString (..))+import Data.Text               (Text)+import Data.Void               (Void)+import Dhall.Map               (Map)+import Dhall.Src               (Src (..))+import Prettyprinter           (Pretty (..))+import Text.Parser.Combinators (try, (<?>))+import Text.Parser.Token       (TokenParsing (..))  import qualified Control.Monad.Fail-import qualified Data.Char-import qualified Data.Set+import qualified Data.Char                   as Char import qualified Data.Text-import qualified Data.Text.Prettyprint.Doc.Render.String as Pretty import qualified Dhall.Map import qualified Dhall.Pretty-import qualified Dhall.Set+import qualified Prettyprinter.Render.String as Pretty import qualified Text.Megaparsec import qualified Text.Megaparsec.Char import qualified Text.Parser.Char@@ -139,14 +136,8 @@     -- {-# INLINE mplus #-}  instance Text.Megaparsec.MonadParsec Void Text Parser where-#if MIN_VERSION_megaparsec(8, 0, 0)     parseError e = Parser (Text.Megaparsec.parseError e)-#else-    failure u e    = Parser (Text.Megaparsec.failure u e) -    fancyFailure e = Parser (Text.Megaparsec.fancyFailure e)-#endif-     label l (Parser p) = Parser (Text.Megaparsec.label l p)      hidden (Parser p) = Parser (Text.Megaparsec.hidden p)@@ -178,6 +169,10 @@      updateParserState f = Parser (Text.Megaparsec.updateParserState f) +#if MIN_VERSION_megaparsec(9,4,0)+    mkParsec f = Parser (Text.Megaparsec.mkParsec f)+#endif+ instance Semigroup a => Semigroup (Parser a) where     (<>) = liftA2 (<>) @@ -218,7 +213,7 @@ instance TokenParsing Parser where     someSpace =         Text.Parser.Token.Style.buildSomeSpaceParser-            (Parser (Text.Megaparsec.skipSome (Text.Megaparsec.satisfy Data.Char.isSpace)))+            (Parser (Text.Megaparsec.skipSome (Text.Megaparsec.satisfy Char.isSpace)))             Text.Parser.Token.Style.haskellCommentStyle      highlight _ = id@@ -264,16 +259,6 @@ takeWhile1 :: (Char -> Bool) -> Parser Text takeWhile1 predicate = Parser (Text.Megaparsec.takeWhile1P Nothing predicate) --- | Construct a 'Set a' from a '[a]', failing if there was a duplicate element-noDuplicates :: Ord a => [a] -> Parser (Set a)-noDuplicates = go Dhall.Set.empty-  where-    go found    []  = return found-    go found (x:xs) =-        if Data.Set.member x (Dhall.Set.toSet found)-        then fail "Duplicate key"-        else go (Dhall.Set.append x found) xs- -- | Creates a map with the given key-value pairs, failing if there was a --   duplicate key. toMap :: [(Text, a)] -> Parser (Map Text a)@@ -293,3 +278,15 @@ toMapWith combine kvs = sequence m   where     m = Dhall.Map.fromListWithKey combine (map (\(k, v) -> (k, pure v)) kvs)++-- | Convert a list of digits to the equivalent number+base :: Num n => [Char] -> n -> n+digits `base` b = foldl snoc 0 (map (fromIntegral . digitToNumber) digits)+  where+    snoc result number = result * b + number++    digitToNumber c+        | '0' <= c && c <= '9' = 0x0 + Char.ord c - Char.ord '0'+        | 'A' <= c && c <= 'F' = 0xA + Char.ord c - Char.ord 'A'+        | 'a' <= c && c <= 'f' = 0xa + Char.ord c - Char.ord 'a'+        | otherwise = error "Invalid hexadecimal digit"
src/Dhall/Parser/Expression.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP                 #-} {-# LANGUAGE NamedFieldPuns      #-} {-# LANGUAGE OverloadedLists     #-} {-# LANGUAGE OverloadedStrings   #-}@@ -8,9 +9,7 @@ module Dhall.Parser.Expression where  import Control.Applicative     (Alternative (..), liftA2, optional)-import Data.ByteArray.Encoding (Base (..)) import Data.Foldable           (foldl')-import Data.Functor            (void) import Data.List.NonEmpty      (NonEmpty (..)) import Data.Text               (Text) import Dhall.Src               (Src (..))@@ -20,14 +19,15 @@ 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+import qualified Data.ByteString                    as ByteString+import qualified Data.ByteString.Base16             as Base16 import qualified Data.Char                          as Char import qualified Data.List import qualified Data.List.NonEmpty                 as NonEmpty import qualified Data.Sequence import qualified Data.Text import qualified Data.Text.Encoding+import qualified Data.Time                          as Time import qualified Dhall.Crypto import qualified Text.Megaparsec @@ -107,14 +107,186 @@ data Parsers a = Parsers     { completeExpression_ :: Parser (Expr Src a)     , importExpression_   :: Parser (Expr Src a)+    , letBinding          :: Parser (Binding Src a)     } --- | Given a parser for imports, +{-| Parse a numeric `TimeZone`++    This corresponds to the @time-numoffset@ rule from the official grammar+-}+timeNumOffset :: Parser (Expr s a)+timeNumOffset = do+    s <- signPrefix++    hour <- timeHour++    _ <- text ":"++    minute <- timeMinute++    let minutes = s (hour * 60 + minute)++    return (TimeZoneLiteral (Time.TimeZone minutes Prelude.False ""))++{-| Parse a numeric `TimeZone` or a @Z@++    This corresponds to the @time-offset@ rule from the official grammar+-}+timeOffset :: Parser (Expr s a)+timeOffset =+        (do _ <- text "Z"++            return (TimeZoneLiteral (Time.TimeZone 0 Prelude.False ""))+        )+    <|> timeNumOffset++{-| Parse a `Time`++    This corresponds to the @partial-time@ rule from the official grammar+-}+partialTime :: Parser (Expr s a)+partialTime = do+    hour <- timeHour++    _ <- text ":"++    minute <- timeMinute++    _ <- text ":"++    second <- timeSecond++    (fraction, precision) <- timeSecFrac <|> pure (0, 0)++    let time = Time.TimeOfDay hour minute (second + fraction)++    return (TimeLiteral time precision)++{-| Parse a `Date`++    This corresponds to the @full-date@ rule from the official grammar+-}+fullDate :: Parser (Expr s a)+fullDate = do+    year <- dateFullYear++    _ <- text "-"++    month <- dateMonth++    _ <- text "-"++    day <- dateMday++    case Time.fromGregorianValid year month day of+        Nothing -> fail "Invalid calendar day"+        Just d  -> return (DateLiteral d)++{-| Parse a `Date`, `Time`, `TimeZone` or any valid permutation of them as a+    record++    This corresponds to the @temporal-literal@ rule from the official grammar+-}+temporalLiteral :: Parser (Expr s a)+temporalLiteral =+        try (do+            date <- fullDate++            _ <- text "T" <|> text "t"++            time <- partialTime++            timeZone <- timeOffset++            return+                (RecordLit+                    [   ("date"    , makeRecordField date)+                    ,   ("time"    , makeRecordField time)+                    ,   ("timeZone", makeRecordField timeZone)+                    ]+                )+        )+    <|> try (do+            date <- fullDate++            _ <- text "T" <|> text "t"++            time <- partialTime++            return+                (RecordLit+                    [   ("date", makeRecordField date)+                    ,   ("time", makeRecordField time)+                    ]+                )+        )+    <|> try (do+            time <- partialTime++            timeZone <- timeOffset++            return+                (RecordLit+                    [   ("time"    , makeRecordField time)+                    ,   ("timeZone", makeRecordField timeZone)+                    ]+                )+        )+    <|> try fullDate+    <|> try partialTime+    <|> try timeNumOffset++-- | Parse a \"shebang\" line (i.e. an initial line beginning with @#!@)+shebang :: Parser ()+shebang = do+    _ <- text "#!"++    let predicate c = ('\x20' <= c && c <= '\x10FFFF') || c == '\t'++    _ <- Dhall.Parser.Combinators.takeWhile predicate++    _ <- endOfLine++    return ()++-- | Given a parser for imports, parsers :: forall a. Parser a -> Parsers a-parsers embedded = Parsers {..}+parsers embedded = Parsers{..}   where-    completeExpression_ = whitespace *> expression <* whitespace+    completeExpression_ =+            whitespace+        *>  expression+        <*  whitespace+        <*  optional lineCommentPrefix +    letBinding = do+        src0 <- try (_let *> src nonemptyWhitespace)++        c <- label++        src1 <- src whitespace++        d <- optional (do+            _colon++            src2 <- src nonemptyWhitespace++            e <- expression++            whitespace++            return (Just src2, e) )++        _equal++        src3 <- src whitespace++        f <- expression++        whitespace++        return (Binding (Just src0) c (Just src1) d (Just src3) f)+     expression =         noted             ( choice@@ -128,7 +300,7 @@             ) <?> "expression"       where         alternative0 = do-            _lambda+            cs <- _lambda             whitespace             _openParens             src0 <- src whitespace@@ -140,10 +312,10 @@             whitespace             _closeParens             whitespace-            _arrow+            cs' <- _arrow             whitespace             c <- expression-            return (Lam (FunctionBinding (Just src0) a (Just src1) (Just src2) b) c)+            return (Lam (Just (cs <> cs')) (FunctionBinding (Just src0) a (Just src1) (Just src2) b) c)          alternative1 = do             try (_if *> nonemptyWhitespace)@@ -157,35 +329,7 @@             return (BoolIf a b c)          alternative2 = do-            let binding = do-                    src0 <- try (_let *> src nonemptyWhitespace)--                    c <- label--                    src1 <- src whitespace--                    d <- optional (do-                        _colon--                        src2 <- src nonemptyWhitespace--                        e <- expression--                        whitespace--                        return (Just src2, e) )--                    _equal--                    src3 <- src whitespace--                    f <- expression--                    whitespace--                    return (Binding (Just src0) c (Just src1) d (Just src3) f)--            as <- NonEmpty.some1 binding+            as <- NonEmpty.some1 letBinding              try (_in *> nonemptyWhitespace) @@ -211,7 +355,7 @@             return (Dhall.Syntax.wrapInLets as b)          alternative3 = do-            try (_forall *> whitespace *> _openParens)+            cs <- try (_forall <* whitespace <* _openParens)             whitespace             a <- label             whitespace@@ -221,10 +365,10 @@             whitespace             _closeParens             whitespace-            _arrow+            cs' <- _arrow             whitespace             c <- expression-            return (Pi a b c)+            return (Pi (Just (cs <> cs')) a b c)          alternative4 = do             try (_assert *> whitespace *> _colon)@@ -244,10 +388,14 @@                         _          -> empty                      bs <- some (do-                        try (whitespace *> _with *> nonemptyWhitespace)+                        try (nonemptyWhitespace *> _with *> nonemptyWhitespace) -                        keys <- Combinators.NonEmpty.sepBy1 anyLabel (try (whitespace *> _dot) *> whitespace)+                        let withComponent =+                                    fmap WithLabel anyLabelOrSome+                                <|> fmap (\_ -> WithQuestion) (text "?") +                        keys <- Combinators.NonEmpty.sepBy1 withComponent (try (whitespace *> _dot) *> whitespace)+                         whitespace                          _equal@@ -266,26 +414,26 @@                     whitespace                      let alternative5B0 = do-                            _arrow+                            cs <- _arrow                             whitespace                             b <- expression                             whitespace-                            return (Pi "_" a b)+                            return (Pi (Just cs) "_" a b)                      let alternative5B1 = do                             _colon                             nonemptyWhitespace                             case (shallowDenote a, a0Info) of                                 (ListLit Nothing [], _) -> do-                                    b <- applicationExpression+                                    b <- expression                                      return (ListLit (Just b) [])                                 (Merge c d Nothing, NakedMergeOrSomeOrToMap) -> do-                                    b <- applicationExpression+                                    b <- expression                                      return (Merge c d (Just b))                                 (ToMap c Nothing, NakedMergeOrSomeOrToMap) -> do-                                    b <- applicationExpression+                                    b <- expression                                      return (ToMap c (Just b))                                 _ -> do@@ -341,20 +489,20 @@      operatorParsers :: [Parser (Expr s a -> Expr s a -> Expr s a)]     operatorParsers =-        [ Equivalent              <$ _equivalent   <* whitespace-        , ImportAlt               <$ _importAlt    <* nonemptyWhitespace-        , BoolOr                  <$ _or           <* whitespace-        , NaturalPlus             <$ _plus         <* nonemptyWhitespace-        , TextAppend              <$ _textAppend   <* whitespace-        , ListAppend              <$ _listAppend   <* whitespace-        , BoolAnd                 <$ _and          <* whitespace-        , Combine Nothing         <$ _combine      <* whitespace-        , Prefer PreferFromSource <$ _prefer       <* whitespace-        , CombineTypes            <$ _combineTypes <* whitespace-        , NaturalTimes            <$ _times        <* whitespace+        [ Equivalent . Just           <$> _equivalent   <* whitespace+        , ImportAlt                   <$ _importAlt     <* nonemptyWhitespace+        , BoolOr                      <$ _or            <* whitespace+        , NaturalPlus                 <$ _plus          <* nonemptyWhitespace+        , TextAppend                  <$ _textAppend    <* whitespace+        , ListAppend                  <$ _listAppend    <* whitespace+        , BoolAnd                     <$ _and           <* whitespace+        , (\cs -> Combine (Just cs) Nothing)         <$> _combine <* whitespace+        , (\cs -> Prefer (Just cs) PreferFromSource) <$> _prefer  <* whitespace+        , CombineTypes . Just         <$> _combineTypes <* whitespace+        , NaturalTimes                <$ _times         <* whitespace         -- Make sure that `==` is not actually the prefix of `===`-        , BoolEQ                  <$ try (_doubleEqual <* Text.Megaparsec.notFollowedBy (char '=')) <* whitespace-        , BoolNE                  <$ _notEqual     <* whitespace+        , BoolEQ                      <$ try (_doubleEqual <* Text.Megaparsec.notFollowedBy (char '=')) <* whitespace+        , BoolNE                      <$ _notEqual      <* whitespace         ]      applicationExpression = snd <$> applicationExpressionWithInfo@@ -378,10 +526,15 @@                      return (\a -> ToMap a Nothing, Just "argument to ❰toMap❱") -            let alternative3 =+            let alternative3 = do+                    try (_showConstructor *> nonemptyWhitespace)++                    return (\a -> ShowConstructor a, Just "argument to ❰showConstructor❱")++            let alternative4 =                     return (id, Nothing) -            (f, maybeMessage) <- alternative0 <|> alternative1 <|> alternative2 <|> alternative3+            (f, maybeMessage) <- alternative0 <|> alternative1 <|> alternative2 <|> alternative3 <|> alternative4              let adapt parser =                     case maybeMessage of@@ -437,35 +590,44 @@     selectorExpression = noted (do             a <- primitiveExpression -            let recordType = whitespace *> _openParens *> whitespace *> expression <* whitespace <* _closeParens+            let recordType = _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+            let alternatives = 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 fieldSelection = do+                            l <- anyLabel -            let alternatives =-                        fmap field               fieldSelection-                    <|> fmap projectBySet        (whitespace *> labels)-                    <|> fmap projectByExpression recordType+                            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 result =+                                fmap field               fieldSelection+                            <|> fmap projectBySet        labels+                            <|> fmap projectByExpression recordType++                    result+             b <- Text.Megaparsec.many (try (whitespace *> _dot *> alternatives))+             return (foldl' (\e k -> k e) a b) )      primitiveExpression =             noted                 ( choice-                    [ alternative00+                    [ bytesLiteral+                    , temporalLiteral+                    , alternative00                     , alternative01                     , alternative02                     , textLiteral@@ -561,7 +723,9 @@                      'D' ->                         choice-                            [ DoubleShow       <$ _DoubleShow+                            [ DateShow         <$ _DateShow+                            , Date             <$ _Date+                            , DoubleShow       <$ _DoubleShow                             , Double           <$ _Double                             ]                     'L' ->@@ -576,13 +740,21 @@                             , List             <$ _List                             ]                     'O' ->    Optional         <$ _Optional-                    'B' ->    Bool             <$ _Bool+                    'B' ->+                        choice+                            [ Bool             <$ _Bool+                            , Bytes            <$ _Bytes+                            ]                     'S' ->    Const Sort       <$ _Sort                     'T' ->                         choice                             [ TextReplace      <$ _TextReplace                             , TextShow         <$ _TextShow                             , Text             <$ _Text+                            , TimeZoneShow     <$ _TimeZoneShow+                            , TimeZone         <$ _TimeZone+                            , TimeShow         <$ _TimeShow+                            , Time             <$ _Time                             , BoolLit True     <$ _True                             , Const Type       <$ _Type                             ]@@ -671,7 +843,7 @@                      let fourCharacterEscapeSequence = do                             ns <- Control.Monad.replicateM 4 hexNumber-                            +                             let number = toNumber ns                              Control.Monad.guard (validCodepoint number)@@ -711,7 +883,7 @@                 , unescapedCharacterFast                 , unescapedCharacterSlow                 , tab-                , endOfLine+                , endOfLine_                 ]           where                 escapeSingleQuotes = do@@ -750,7 +922,7 @@                   where                     predicate c = c == '$' || c == '\'' -                endOfLine = do+                endOfLine_ = do                     a <- "\n" <|> "\r\n"                     b <- singleQuoteContinue                     return (Chunks [] a <> b)@@ -762,17 +934,31 @@      singleQuoteLiteral = do             _ <- text "''"+             _ <- endOfLine+             a <- singleQuoteContinue              return (Dhall.Syntax.toDoubleQuoted a)-          where-            endOfLine = (void (char '\n') <|> void (text "\r\n")) <?> "newline"      textLiteral = (do-            literal <- doubleQuotedLiteral <|> singleQuoteLiteral-            return (TextLit literal) ) <?> "literal"+        literal <- doubleQuotedLiteral <|> singleQuoteLiteral+        return (TextLit literal) ) <?> "literal" +    bytesLiteral = (do+        _ <- text "0x\""++        let byte = do+                nibble0 <- Text.Megaparsec.satisfy hexdig+                nibble1 <- Text.Megaparsec.satisfy hexdig+                return ([nibble0, nibble1] `base` 16)++        bytes <- Text.Megaparsec.many byte++        _ <- char '"'++        return (BytesLit (ByteString.pack bytes)) ) <?> "literal"+     recordTypeOrLiteral firstSrc0 =             choice                 [ emptyRecordLiteral@@ -876,7 +1062,7 @@                      whitespace -                    let combine k = liftA2 $ \rf rf' -> makeRecordField $ Combine (Just k)+                    let combine k = liftA2 $ \rf rf' -> makeRecordField $ Combine mempty (Just k)                                                             (recordFieldValue rf')                                                             (recordFieldValue rf) @@ -916,8 +1102,6 @@             let emptyUnionType = do                     try (optional (_bar *> whitespace) *> _closeAngle) -                    _ <- optional (_bar *> whitespace)-                     return (Union mempty)              nonEmptyUnionType <|> emptyUnionType ) <?> "literal"@@ -1050,9 +1234,9 @@     _ <- text "sha256:"     t <- count 64 (satisfy hexdig <?> "hex digit")     let strictBytes16 = Data.Text.Encoding.encodeUtf8 t-    strictBytes <- case Data.ByteArray.Encoding.convertFromBase Base16 strictBytes16 of+    strictBytes <- case Base16.decode strictBytes16 of         Left  string      -> fail string-        Right strictBytes -> return (strictBytes :: Data.ByteString.ByteString)+        Right strictBytes -> return strictBytes     case Dhall.Crypto.sha256DigestFromByteString strictBytes of       Nothing -> fail "Invalid sha256 hash"       Just h  -> pure h@@ -1080,7 +1264,9 @@     alternative = do       try (whitespace *> _as *> nonemptyWhitespace) -      (_Text >> pure RawText) <|> (_Location >> pure Location)+      (_Text >> pure RawText)+          <|> (_Location >> pure Location)+          <|> (_Bytes >> pure RawBytes)  -- | 'ApplicationExprInfo' distinguishes certain subtypes of application -- expressions.
src/Dhall/Parser/Token.hs view
@@ -4,9 +4,11 @@ -- | Parse Dhall tokens. Even though we don't have a tokenizer per-se this ---  module is useful for keeping some small parsing utilities. module Dhall.Parser.Token (+    endOfLine,     validCodepoint,     whitespace,     lineComment,+    lineCommentPrefix,     blockComment,     nonemptyWhitespace,     bashEnvironmentVariable,@@ -23,10 +25,18 @@     hexdig,     identifier,     hexNumber,+    signPrefix,     doubleLiteral,     doubleInfinity,     naturalLiteral,     integerLiteral,+    dateFullYear,+    dateMonth,+    dateMday,+    timeHour,+    timeMinute,+    timeSecond,+    timeSecFrac,     _Optional,     _if,     _then,@@ -37,6 +47,7 @@     _using,     _merge,     _toMap,+    _showConstructor,     _assert,     _Some,     _None,@@ -61,12 +72,19 @@     _ListIndexed,     _ListReverse,     _Bool,+    _Bytes,     _Natural,     _Integer,     _Double,     _Text,     _TextReplace,     _TextShow,+    _Date,+    _DateShow,+    _Time,+    _TimeShow,+    _TimeZone,+    _TimeZoneShow,     _List,     _True,     _False,@@ -114,13 +132,14 @@  import Control.Applicative     (Alternative (..), optional) import Data.Bits               ((.&.))+import Data.Fixed              (Pico) import Data.Functor            (void, ($>))+import Data.Ratio              ((%)) import Data.Text               (Text)-import Dhall.Set               (Set) import Dhall.Syntax import Text.Parser.Combinators (choice, try, (<?>)) -import qualified Control.Monad+import qualified Control.Monad              as Monad import qualified Data.Char                  as Char import qualified Data.Foldable import qualified Data.HashSet@@ -128,7 +147,6 @@ import qualified Data.List.NonEmpty import qualified Data.Scientific            as Scientific import qualified Data.Text-import qualified Dhall.Set import qualified Text.Megaparsec import qualified Text.Megaparsec.Char.Lexer import qualified Text.Parser.Char@@ -137,12 +155,18 @@  import Numeric.Natural (Natural) +-- | Match an end-of-line character sequence+endOfLine :: Parser Text+endOfLine =+    (   Text.Parser.Char.text "\n"  +    <|> Text.Parser.Char.text "\r\n"+    ) <?> "newline"  -- | Returns `True` if the given `Int` is a valid Unicode codepoint validCodepoint :: Int -> Bool validCodepoint c =-    not (category == Char.Surrogate -      || c .&. 0xFFFE == 0xFFFE +    not (category == Char.Surrogate+      || c .&. 0xFFFE == 0xFFFE       || c .&. 0xFFFF == 0xFFFF)   where     category = Char.generalCategory (Char.chr c)@@ -180,6 +204,7 @@     ||  ('A' <= c && c <= 'F')     ||  ('a' <= c && c <= 'f') +-- | Parse a leading @+@ or @-@ sign signPrefix :: Num a => Parser (a -> a) signPrefix = (do     let positive = fmap (\_ -> id    ) (char '+')@@ -268,17 +293,20 @@     a    <- naturalLiteral     return (sign (fromIntegral a)) ) <?> "literal" -{-| Parse a `Dhall.Syntax.Natural` literal +{-| Parse a `Dhall.Syntax.Natural` literal      This corresponds to the @natural-literal@ rule from the official grammar -} naturalLiteral :: Parser Natural naturalLiteral = (do-    a <-    try (char '0' >> char 'x' >> Text.Megaparsec.Char.Lexer.hexadecimal)+    a <-    binary+        <|> hexadecimal         <|> decimal         <|> (char '0' $> 0)     return a ) <?> "literal"   where+    binary = try (char '0' >> char 'b' >> Text.Megaparsec.Char.Lexer.binary)+    hexadecimal = try (char '0' >> char 'x' >> Text.Megaparsec.Char.Lexer.hexadecimal)     decimal = do         n <- headDigit         ns <- many tailDigit@@ -298,7 +326,100 @@           where             step acc x = acc * 10 + x +{-| Parse a 4-digit year +    This corresponds to the @date-fullyear@ rule from the official grammar+-}+dateFullYear :: Parser Integer+dateFullYear = do+    digits <- Monad.replicateM 4 (Text.Parser.Char.satisfy digit)++    return (digits `base` 10)++{-| Parse a 2-digit month++    This corresponds to the @date-month@ rule from the official grammar+-}+dateMonth :: Parser Int+dateMonth = do+    digits <- Monad.replicateM 2 (Text.Parser.Char.satisfy digit)++    let month = digits `base` 10++    if 1 <= month && month <= 12+        then return month+        else fail "Invalid month"++{-| Parse a 2-digit day of the month++    This corresponds to the @date-mday@ rule from the official grammar+-}+dateMday :: Parser Int+dateMday = do+    digits <- Monad.replicateM 2 (Text.Parser.Char.satisfy digit)++    let day = digits `base` 10++    if 1 <= day && day <= 31+        then return day+        else fail "Invalid day"++{-| Parse a 2-digit hour++    This corresponds to the @time-hour@ rule from the official grammar+-}+timeHour :: Parser Int+timeHour = do+    digits <- Monad.replicateM 2 (Text.Parser.Char.satisfy digit)++    let hour = digits `base` 10++    if 0 <= hour && hour < 24+        then return hour+        else fail "Invalid hour"++{-| Parse a 2-digit minute++    This corresponds to the @time-minute@ rule from the official grammar+-}+timeMinute :: Parser Int+timeMinute = do+    digits <- Monad.replicateM 2 (Text.Parser.Char.satisfy digit)++    let minute = digits `base` 10++    if 0 <= minute && minute < 60+        then return minute+        else fail "Invalid minute"++{-| Parse a 2-digit second++    This corresponds to the @time-second@ rule from the official grammar+-}+timeSecond :: Parser Pico+timeSecond = do+    digits <- Monad.replicateM 2 (Text.Parser.Char.satisfy digit)++    let second = digits `base` 10++    if 0 <= second && second < 60+        then return second+        else fail "Invalid second"++{-| Parse the fractional component of a second++    This corresponds to the @time-secfrac@ rule from the official grammar+-}+timeSecFrac :: Parser (Pico, Word)+timeSecFrac = do+    _ <- Text.Parser.Char.text "."++    digits <- some (Text.Parser.Char.satisfy digit)++    let precision = fromIntegral (length digits)++    return (fromRational ((digits `base` 10) % (10 ^ precision)), precision)+ {-| Parse an identifier (i.e. a variable or built-in)      Variables can have an optional index to disambiguate shadowed variables@@ -352,25 +473,23 @@       where         predicate c = 'a' <= c && c <= 'f' --- | Parse a Dhall's single-line comment, starting from `--` and until the---   last character of the line /before/ the end-of-line character-lineComment :: Parser Text-lineComment = do+-- | Same as `lineComment` except that this doesn't parse the end-of-line+--   character+lineCommentPrefix :: Parser Text+lineCommentPrefix = do     _ <- text "--"      let predicate c = ('\x20' <= c && c <= '\x10FFFF') || c == '\t'      commentText <- Dhall.Parser.Combinators.takeWhile predicate -    endOfLine-     return ("--" <> commentText)-  where-    endOfLine =-        (   void (Text.Parser.Char.char '\n'  )-        <|> void (Text.Parser.Char.text "\r\n")-        ) <?> "newline" +-- | Parse a Dhall's single-line comment, starting from `--` and until the+--   last character of the line /before/ the end-of-line character+lineComment :: Parser Text+lineComment = try (lineCommentPrefix <* endOfLine)+ -- | Parsed text doesn't include opening braces blockComment :: Parser Text blockComment = do@@ -398,8 +517,6 @@       where         predicate c = '\x20' <= c && c <= '\x10FFFF' || c == '\n' || c == '\t' -    endOfLine = (Text.Parser.Char.text "\r\n" <?> "newline")- blockCommentContinue :: Parser Text blockCommentContinue = endOfComment <|> continue   where@@ -417,7 +534,7 @@     let t = Data.Text.cons c rest     let isNotAKeyword = not $ t `Data.HashSet.member` reservedKeywords     let isNotAReservedIdentifier = not $ t `Data.HashSet.member` reservedIdentifiers-    Control.Monad.guard (isNotAKeyword && (allowReserved || isNotAReservedIdentifier))+    Monad.guard (isNotAKeyword && (allowReserved || isNotAReservedIdentifier))     return t  headCharacter :: Char -> Bool@@ -443,22 +560,18 @@      This corresponds to the @labels@ rule in the official grammar -}-labels :: Parser (Set Text)+labels :: Parser [Text] labels = do     _openBrace      whitespace -    xs <- nonEmptyLabels <|> emptyLabels--    _ <- optional (_comma *> whitespace)--    return xs+    nonEmptyLabels <|> emptyLabels   where     emptyLabels = do         try (optional (_comma *> whitespace) *> _closeBrace) -        pure Dhall.Set.empty+        pure []      nonEmptyLabels = do         x  <- try (optional (_comma *> whitespace) *> anyLabelOrSome)@@ -471,7 +584,7 @@          _closeBrace -        noDuplicates (x : xs)+        return (x : xs)  {-| Parse a label (e.g. a variable\/field\/alternative name) @@ -847,6 +960,13 @@ _toMap :: Parser () _toMap = keyword "toMap" +{-| Parse the @showConstructor@ keyword++    This corresponds to the @showConstructor@ rule from the official grammar+-}+_showConstructor :: Parser ()+_showConstructor = keyword "showConstructor"+ {-| Parse the @assert@ keyword      This corresponds to the @assert@ rule from the official grammar@@ -1019,6 +1139,13 @@ _Bool :: Parser () _Bool = builtin "Bool" +{-| Parse the @Bytes@ built-in++    This corresponds to the @Bytes@ rule from the official grammar+-}+_Bytes :: Parser ()+_Bytes = builtin "Bytes"+ {-| Parse the @Optional@ built-in      This corresponds to the @Optional@ rule from the official grammar@@ -1068,6 +1195,48 @@ _TextShow :: Parser () _TextShow = builtin "Text/show" +{-| Parse the @Date@ bult-in++    This corresponds to the @Date@ rule from the official grammar+-}+_Date :: Parser ()+_Date = builtin "Date"++{-| Parse the @Date/show@ built-in++    This corresponds to the @Date-show@ rule from the official grammar+-}+_DateShow :: Parser ()+_DateShow = builtin "Date/show"++{-| Parse the @Time@ bult-in++    This corresponds to the @Time@ rule from the official grammar+-}+_Time :: Parser ()+_Time = builtin "Time"++{-| Parse the @Time/show@ built-in++    This corresponds to the @Time-show@ rule from the official grammar+-}+_TimeShow :: Parser ()+_TimeShow = builtin "Time/show"++{-| Parse the @TimeZone@ bult-in++    This corresponds to the @TimeZone@ rule from the official grammar+-}+_TimeZone :: Parser ()+_TimeZone = builtin "TimeZone"++{-| Parse the @TimeZone/show@ built-in++    This corresponds to the @TimeZone-show@ rule from the official grammar+-}+_TimeZoneShow :: Parser ()+_TimeZoneShow = builtin "TimeZone/show"+ {-| Parse the @List@ built-in      This corresponds to the @List@ rule from the official grammar@@ -1213,8 +1382,10 @@ _at = reservedChar '@' <?> "\"@\""  -- | Parse the equivalence symbol (@===@ or @≡@)-_equivalent :: Parser ()-_equivalent = (void (char '≡' <?> "\"≡\"") <|> void (text "===")) <?> "operator"+_equivalent :: Parser CharacterSet+_equivalent =+        (Unicode <$ char '≡' <?> "\"≡\"")+    <|> (ASCII <$ text "===" <?> "===")  -- | Parse the @missing@ keyword _missing :: Parser ()@@ -1227,32 +1398,40 @@ _importAlt = operatorChar '?'  -- | Parse the record combine operator (@/\\@ or @∧@)-_combine :: Parser ()-_combine = (void (char '∧' <?> "\"∧\"") <|> void (text "/\\")) <?> "operator"+_combine :: Parser CharacterSet+_combine =+        (Unicode <$ char '∧' <?> "\"∧\"")+    <|> (ASCII <$ text "/\\" <?> "/\\")  -- | Parse the record type combine operator (@//\\\\@ or @⩓@)-_combineTypes :: Parser ()-_combineTypes = (void (char '⩓' <?> "\"⩓\"") <|> void (text "//\\\\")) <?> "operator"+_combineTypes :: Parser CharacterSet+_combineTypes =+        (Unicode <$ char '⩓' <?> "\"⩓\"")+    <|> (ASCII <$ text "//\\\\" <?> "//\\\\")  -- | Parse the record \"prefer\" operator (@//@ or @⫽@)-_prefer :: Parser ()-_prefer = (void (char '⫽' <?> "\"⫽\"") <|> void (text "//")) <?> "operator"+_prefer :: Parser CharacterSet+_prefer =+        (Unicode <$ char '⫽' <?> "\"⫽\"")+    <|> (ASCII <$ text "//" <?> "//")  -- | Parse a lambda (@\\@ or @λ@)-_lambda :: Parser ()-_lambda = void (Text.Parser.Char.satisfy predicate) <?> "\\"-  where-    predicate 'λ'  = True-    predicate '\\' = True-    predicate _    = False+_lambda :: Parser CharacterSet+_lambda =+        (Unicode <$ char 'λ' <?> "\"λ\"")+    <|> (ASCII <$ char '\\' <?> "\\")  -- | Parse a forall (@forall@ or @∀@)-_forall :: Parser ()-_forall = (void (char '∀' <?> "\"∀\"") <|> void (text "forall")) <?> "forall"+_forall :: Parser CharacterSet+_forall =+        (Unicode <$ char '∀' <?> "\"∀\"")+    <|> (ASCII <$ text "forall" <?> "forall")  -- | Parse a right arrow (@->@ or @→@)-_arrow :: Parser ()-_arrow = (void (char '→' <?> "\"→\"") <|> void (text "->")) <?> "->"+_arrow :: Parser CharacterSet+_arrow =+        (Unicode <$ char '→' <?> "\"→\"")+    <|> (ASCII <$ text "->" <?> "->")  -- | Parse a double colon (@::@) _doubleColon :: Parser ()
src/Dhall/Pretty.hs view
@@ -8,13 +8,18 @@     , prettyExpr      , CharacterSet(..)+    , defaultCharacterSet+    , detectCharacterSet     , prettyCharacterSet      , Dhall.Pretty.Internal.layout     , Dhall.Pretty.Internal.layoutOpts      , escapeEnvironmentVariable+    , UnescapedLabel(..)     , escapeLabel++    , temporalToText     ) where  import Dhall.Pretty.Internal
src/Dhall/Pretty/Internal.hs view
@@ -1,7 +1,11 @@-{-# LANGUAGE LambdaCase        #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards   #-}-{-# LANGUAGE ViewPatterns      #-}+{-# LANGUAGE DeriveAnyClass     #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveGeneric      #-}+{-# LANGUAGE DeriveLift         #-}+{-# LANGUAGE LambdaCase         #-}+{-# LANGUAGE OverloadedStrings  #-}+{-# LANGUAGE RecordWildCards    #-}+{-# LANGUAGE ViewPatterns       #-}  {-# OPTIONS_GHC -Wall #-} @@ -16,6 +20,8 @@     , prettySrcExpr      , CharacterSet(..)+    , defaultCharacterSet+    , detectCharacterSet     , prettyCharacterSet     , prettyImportExpression @@ -26,6 +32,7 @@     , prettyEnvironmentVariable      , prettyConst+    , UnescapedLabel(..)     , escapeLabel     , prettyLabel     , prettyAnyLabel@@ -36,6 +43,7 @@     , prettyDouble     , prettyToStrictText     , prettyToString+    , prettyBase16     , layout     , layoutOpts @@ -50,7 +58,7 @@     , comma     , dot     , equals-    , forall+    , forall_     , label     , lambda     , langle@@ -63,31 +71,48 @@     , rbrace     , rbracket     , rparen++    , temporalToText     ) where -import Data.Foldable-import Data.List.NonEmpty        (NonEmpty (..))-import Data.Text                 (Text)-import Data.Text.Prettyprint.Doc (Doc, Pretty, space)-import Dhall.Map                 (Map)-import Dhall.Set                 (Set)-import Dhall.Src                 (Src (..))-import Dhall.Syntax-import Numeric.Natural           (Natural)+import                Control.DeepSeq               (NFData)+import                Data.Aeson+    ( FromJSON (..)+    , Value (String)+    )+import                Data.Aeson.Types              (typeMismatch, unexpected)+import                Data.ByteString               (ByteString)+import                Data.Data                     (Data)+import                Data.Foldable+import                Data.List.NonEmpty            (NonEmpty (..))+import                Data.Text                     (Text)+import                Dhall.Map                     (Map)+import                Dhall.Src                     (Src (..))+import                Dhall.Syntax+import {-# SOURCE #-} Dhall.Syntax.Instances.Pretty ()+import                GHC.Generics                  (Generic)+import                Language.Haskell.TH.Syntax    (Lift)+import                Lens.Micro                    (cosmosOf, foldMapOf)+import                Numeric.Natural               (Natural)+import                Prettyprinter                 (Doc, Pretty, space) +import qualified Control.Exception             as Exception+import qualified Data.ByteString.Base16        as Base16 import qualified Data.Char import qualified Data.HashSet-import qualified Data.List-import qualified Data.List.NonEmpty                        as NonEmpty+import qualified Data.List                     as 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-import qualified Data.Text.Prettyprint.Doc.Render.String   as Pretty-import qualified Data.Text.Prettyprint.Doc.Render.Terminal as Terminal-import qualified Data.Text.Prettyprint.Doc.Render.Text     as Pretty-import qualified Dhall.Map                                 as Map-import qualified Dhall.Set+import qualified Data.Text                     as Text+import qualified Data.Text.Encoding            as Encoding+import qualified Data.Time                     as Time+import qualified Dhall.Map                     as Map+import qualified Dhall.Syntax.Operations       as Operations+import qualified Prettyprinter                 as Pretty+import qualified Prettyprinter.Render.String   as Pretty+import qualified Prettyprinter.Render.Terminal as Terminal+import qualified Prettyprinter.Render.Text     as Pretty+import qualified Text.Printf                   as Printf  {-| Annotation type used to tag elements in a pretty-printed document for     syntax highlighting purposes@@ -113,14 +138,51 @@ annToAnsiStyle Operator = Terminal.bold <> Terminal.colorDull Terminal.Green  -- | This type determines whether to render code as `ASCII` or `Unicode`-data CharacterSet = ASCII | Unicode deriving Show+data CharacterSet = ASCII | Unicode+    deriving (Eq, Ord, Show, Data, Generic, Lift, NFData) +-- | Since ASCII is a subset of Unicode, if either argument is Unicode, the+-- result is Unicode+instance Semigroup CharacterSet where+    Unicode <> _ = Unicode+    _ <> other = other++instance Monoid CharacterSet where+    mempty = ASCII++instance FromJSON CharacterSet where+  parseJSON (String "unicode") = pure Unicode+  parseJSON (String "ascii") = pure ASCII+  parseJSON v@(String _) = unexpected v+  parseJSON v = typeMismatch "String" v++-- | The character set used by default in functions throughout the Dhall code+-- base.+defaultCharacterSet :: CharacterSet+defaultCharacterSet = Unicode++-- | Detect which character set is used for the syntax of an expression+-- If any parts of the expression uses the Unicode syntax, the whole expression+-- is deemed to be using the Unicode syntax.+detectCharacterSet :: Expr Src a -> CharacterSet+detectCharacterSet = foldMapOf (cosmosOf subExpressions) exprToCharacterSet+  where+    exprToCharacterSet = \case+        Embed _ -> mempty -- Don't go down the embed route, otherwise: <<loop>>+        Lam (Just Unicode) _ _ -> Unicode+        Pi (Just Unicode) _ _ _ -> Unicode+        Combine (Just Unicode) _ _ _ -> Unicode+        CombineTypes (Just Unicode) _ _ -> Unicode+        Prefer (Just Unicode) _ _ _ -> Unicode+        Equivalent (Just Unicode) _ _ -> Unicode+        _ -> mempty+ -- | Pretty print an expression prettyExpr :: Pretty a => Expr s a -> Doc Ann prettyExpr = prettySrcExpr . denote  prettySrcExpr :: Pretty a => Expr Src a -> Doc Ann-prettySrcExpr = prettyCharacterSet Unicode+prettySrcExpr = prettyCharacterSet defaultCharacterSet  {-| Internal utility for pretty-printing, used when generating element lists     to supply to `enclose` or `enclose'`.  This utility indicates that the@@ -261,9 +323,9 @@ lambda Unicode = syntax "λ" lambda ASCII   = syntax "\\" -forall :: CharacterSet -> Doc Ann-forall Unicode = syntax "∀"-forall ASCII   = syntax "forall "+forall_ :: CharacterSet -> Doc Ann+forall_ Unicode = syntax "∀"+forall_ ASCII   = syntax "forall "  rarrow :: CharacterSet -> Doc Ann rarrow Unicode = syntax "→"@@ -348,7 +410,7 @@ arrows :: CharacterSet -> [ Doc Ann ] -> Doc Ann arrows characterSet docs = Pretty.group (Pretty.flatAlt long short)   where-    long = Pretty.align (mconcat (Data.List.intersperse Pretty.hardline docs'))+    long = Pretty.align (mconcat (List.intersperse Pretty.hardline docs'))       where         docs' = case unsnoc docs of             Nothing -> docs@@ -361,7 +423,7 @@                   last' = space <> space <> last_ -    short = mconcat (Data.List.intersperse separator docs)+    short = mconcat (List.intersperse separator docs)       where         separator = space <> rarrow characterSet <> space @@ -420,7 +482,7 @@     combineShort x y = x <> y  {-| Format an expression that holds a variable number of elements without a-    trailing document such as nested `let`, nested lambdas, or nested `forall`s+    trailing document such as nested @let@, nested lambdas, or nested @forall@s -} enclose'     :: Doc ann@@ -440,7 +502,7 @@     longLines = zipWith (<>) (beginLong : repeat sepLong) docsLong      long =-        Pretty.align (mconcat (Data.List.intersperse Pretty.hardline longLines))+        Pretty.align (mconcat (List.intersperse Pretty.hardline longLines))      short = mconcat (zipWith (<>) (beginShort : repeat sepShort) docsShort) @@ -463,29 +525,51 @@ tailCharacter :: Char -> Bool tailCharacter c = alphaNum c || c == '_' || c == '-' || c == '/' +-- | The set of labels which do not need to be escaped+data UnescapedLabel+    = NonReservedLabel+    -- ^ This corresponds to the `nonreserved-label` rule in the grammar+    | AnyLabel+    -- ^ This corresponds to the `any-label` rule in the grammar+    | AnyLabelOrSome+    -- ^ This corresponds to the `any-label-or-some` rule in the grammar+ -- | Escape a label if it is not valid when unquoted-escapeLabel :: Bool -> Text -> Text-escapeLabel allowReserved l =+escapeLabel :: UnescapedLabel -> Text -> Text+escapeLabel allowedLabel l =     case Text.uncons l of         Just (h, t)-            | headCharacter h && Text.all tailCharacter t && (notReservedIdentifier || (allowReserved && someOrNotLanguageKeyword))+            | headCharacter h && Text.all tailCharacter t && allowed && l /= "?"                 -> l         _       -> "`" <> l <> "`"-    where-        notReservedIdentifier = not (Data.HashSet.member l reservedIdentifiers)-        someOrNotLanguageKeyword = l == "Some" || not (Data.HashSet.member l reservedKeywords)+  where+    allowed = case allowedLabel of+        NonReservedLabel -> notReservedIdentifier+        AnyLabel         -> notReservedKeyword+        AnyLabelOrSome   -> notReservedKeyword || l == "Some" -prettyLabelShared :: Bool -> Text -> Doc Ann+    notReservedIdentifier = not (Data.HashSet.member l reservedIdentifiers)++    notReservedKeyword = not (Data.HashSet.member l reservedKeywords)++prettyLabelShared :: UnescapedLabel -> Text -> Doc Ann prettyLabelShared b l = label (Pretty.pretty (escapeLabel b l))  prettyLabel :: Text -> Doc Ann-prettyLabel = prettyLabelShared False+prettyLabel = prettyLabelShared NonReservedLabel  prettyAnyLabel :: Text -> Doc Ann-prettyAnyLabel = prettyLabelShared True+prettyAnyLabel = prettyLabelShared AnyLabel -prettyAnyLabels :: Foldable list => list (Maybe Src, Text, Maybe Src) -> Doc Ann-prettyAnyLabels keys = Pretty.group (Pretty.flatAlt long short)+prettyAnyLabelOrSome :: Text -> Doc Ann+prettyAnyLabelOrSome = prettyLabelShared AnyLabelOrSome++prettyKeys+    :: Foldable list+    => (key -> Doc Ann)+    -> list (Maybe Src, key, Maybe Src)+    -> Doc Ann+prettyKeys prettyK keys = Pretty.group (Pretty.flatAlt long short)   where     short = (mconcat . Pretty.punctuate dot . map prettyKey . toList) keys @@ -505,16 +589,14 @@         . Pretty.punctuate Pretty.hardline         . Data.Maybe.catMaybes         $ [ renderSrcMaybe mSrc0-          , Just (prettyAnyLabel key)+          , Just (prettyK key)           , renderSrcMaybe mSrc1           ] -prettyLabels :: Set Text -> Doc Ann+prettyLabels :: [Text] -> Doc Ann prettyLabels a-    | Data.Set.null (Dhall.Set.toSet a) =-        lbrace <> rbrace-    | otherwise =-        braces (map (duplicate . prettyAnyLabel) (Dhall.Set.toList a))+    | null a    = lbrace <> rbrace+    | otherwise = braces (map (duplicate . prettyAnyLabelOrSome) a)  prettyNumber :: Integer -> Doc Ann prettyNumber = literal . Pretty.pretty@@ -605,10 +687,10 @@     prettyCompleteExpression expression =         Pretty.group (prettyExpression expression) -    prettyExpression a0@(Lam _ _) =+    prettyExpression a0@(Lam _ _ _) =         arrows characterSet (docs a0)       where-        docs (Lam (FunctionBinding { functionBindingVariable = a, functionBindingAnnotation = b }) c) =+        docs (Lam _ (FunctionBinding { functionBindingVariable = a, functionBindingAnnotation = b }) c) =             Pretty.group (Pretty.flatAlt long short) : docs c           where             long =  (lambda characterSet <> space)@@ -654,7 +736,7 @@         longLines = zipWith (<>) prefixesLong (docsLong True a0)          long =-            Pretty.align (mconcat (Data.List.intersperse Pretty.hardline longLines))+            Pretty.align (mconcat (List.intersperse Pretty.hardline longLines))          short = mconcat (zipWith (<>) prefixesShort (docsShort a0)) @@ -697,7 +779,12 @@       where         MultiLet as b = multiLet a0 b0 -        stripSpaces = Text.dropAround (\c -> c == ' ' || c == '\t')+        isSpace c = c == ' ' || c == '\t'+        stripSpaces =+            Text.dropAround isSpace+          . Text.intercalate "\n"+          . map (Text.dropWhileEnd isSpace)+          . Text.splitOn "\n"          -- Strip a single newline character. Needed to ensure idempotency in         -- cases where we add hard line breaks.@@ -736,13 +823,13 @@             ( keyword "in" <> " " <> prettyExpression b             , keyword "in" <> "  "  <> prettyExpression b             )-    prettyExpression a0@(Pi _ _ _) =+    prettyExpression a0@(Pi _ _ _ _) =         arrows characterSet (docs a0)       where-        docs (Pi "_" b c) = prettyOperatorExpression b : docs c-        docs (Pi a   b c) = Pretty.group (Pretty.flatAlt long short) : docs c+        docs (Pi _ "_" b c) = prettyOperatorExpression b : docs c+        docs (Pi _ a   b c) = Pretty.group (Pretty.flatAlt long short) : docs c           where-            long =  forall characterSet <> space+            long =  forall_ characterSet <> space                 <>  Pretty.align                     (   lparen <> space                     <>  prettyLabel a@@ -753,7 +840,7 @@                     <>  rparen                     ) -            short = forall characterSet <> lparen+            short = forall_ characterSet <> lparen                 <>  prettyLabel a                 <>  space <> colon <> space                 <>  prettyExpression b@@ -781,7 +868,11 @@             <>  Pretty.align (keyword "with" <> " " <> update)          (update, _) =-            prettyKeyValue prettyOperatorExpression equals (makeKeyValue b c)+            prettyKeyValue prettyKey prettyOperatorExpression equals+                (makeKeyValue b c)++        prettyKey (WithLabel text) = prettyAnyLabelOrSome text+        prettyKey  WithQuestion    = syntax "?"     prettyExpression (Assert a) =         Pretty.group (Pretty.flatAlt long short)       where@@ -813,7 +904,7 @@                 <>  Pretty.indent 2 (prettyImportExpression_ b)                 <>  Pretty.hardline                 <>  colon <> space-                <>  prettyApplicationExpression c+                <>  prettyExpression c                 )          short = keyword "merge" <> space@@ -821,7 +912,7 @@             <>  " "             <>  prettyImportExpression_ b             <>  space <> colon <> space-            <>  prettyApplicationExpression c+            <>  prettyExpression c     prettyAnnotatedExpression (ToMap a (Just b)) =         Pretty.group (Pretty.flatAlt long short)       where@@ -832,13 +923,13 @@                 <>  Pretty.indent 2 (prettyImportExpression_ a)                 <>  Pretty.hardline                 <>  colon <> space-                <>  prettyApplicationExpression b+                <>  prettyExpression b                 )          short = keyword "toMap" <> space             <>  prettyImportExpression_ a             <>  space <> colon <> space-            <>  prettyApplicationExpression b+            <>  prettyExpression b     prettyAnnotatedExpression a0@(Annot _ _) =         enclose'             ""@@ -858,7 +949,7 @@     prettyAnnotatedExpression (ListLit (Just a) b) =             list (map prettyExpression (Data.Foldable.toList b))         <>  " : "-        <>  prettyApplicationExpression a+        <>  prettyExpression a     prettyAnnotatedExpression a         | Just doc <- preserveSource a =             doc@@ -884,10 +975,10 @@         spacer = if Text.length op == 1 then " "  else "  "      prettyEquivalentExpression :: Pretty a => Expr Src a -> Doc Ann-    prettyEquivalentExpression a0@(Equivalent _ _) =+    prettyEquivalentExpression a0@(Equivalent _ _ _) =         prettyOperator (equivalent characterSet) (docs a0)       where-        docs (Equivalent a b) = prettyImportAltExpression b : docs a+        docs (Equivalent _ a b) = prettyImportAltExpression b : docs a         docs a             | Just doc <- preserveSource a =                 [ doc ]@@ -1024,10 +1115,10 @@             prettyCombineExpression a      prettyCombineExpression :: Pretty a => Expr Src a -> Doc Ann-    prettyCombineExpression a0@(Combine _ _ _) =+    prettyCombineExpression a0@(Combine _ _ _ _) =         prettyOperator (combine characterSet) (docs a0)       where-        docs (Combine _ a b) = prettyPreferExpression b : docs a+        docs (Combine _ _ a b) = prettyPreferExpression b : docs a         docs a             | Just doc <- preserveSource a =                 [ doc ]@@ -1047,7 +1138,7 @@     prettyPreferExpression a0@(Prefer {}) =         prettyOperator (prefer characterSet) (docs a0)       where-        docs (Prefer _ a b) = prettyCombineTypesExpression b : docs a+        docs (Prefer _ _ a b) = prettyCombineTypesExpression b : docs a         docs a             | Just doc <- preserveSource a =                 [ doc ]@@ -1064,10 +1155,10 @@             prettyCombineTypesExpression a      prettyCombineTypesExpression :: Pretty a => Expr Src a -> Doc Ann-    prettyCombineTypesExpression a0@(CombineTypes _ _) =+    prettyCombineTypesExpression a0@(CombineTypes _ _ _) =         prettyOperator (combineTypes characterSet) (docs a0)       where-        docs (CombineTypes a b) = prettyTimesExpression b : docs a+        docs (CombineTypes _ a b) = prettyTimesExpression b : docs a         docs a             | Just doc <- preserveSource a =                 [ doc ]@@ -1151,6 +1242,7 @@             Some a            -> app (builtin "Some") (a : args)             Merge a b Nothing -> app (keyword "merge") (a : b : args)             ToMap a Nothing   -> app (keyword "toMap") (a : args)+            ShowConstructor a -> app (keyword "showConstructor") (a : args)             e | Note _ b <- e ->                   go args b               | null args ->@@ -1224,6 +1316,8 @@         prettyConst k     prettyPrimitiveExpression Bool =         builtin "Bool"+    prettyPrimitiveExpression Bytes =+        builtin "Bytes"     prettyPrimitiveExpression Natural =         builtin "Natural"     prettyPrimitiveExpression NaturalFold =@@ -1262,6 +1356,57 @@         builtin "Text/replace"     prettyPrimitiveExpression TextShow =         builtin "Text/show"+    prettyPrimitiveExpression Date =+        builtin "Date"+    prettyPrimitiveExpression (DateLiteral day) =+        literal+            (   Pretty.pretty (Printf.printf "%04d" _HHHH :: String)+            <>  "-"+            <>  Pretty.pretty (Printf.printf "%02d" _MM :: String)+            <>  "-"+            <>  Pretty.pretty (Printf.printf "%02d" _DD :: String)+            )+      where+        (_HHHH, _MM, _DD) = Time.toGregorian day+    prettyPrimitiveExpression DateShow =+        builtin "Date/show"+    prettyPrimitiveExpression Time =+        builtin "Time"+    prettyPrimitiveExpression (TimeLiteral (Time.TimeOfDay hh mm seconds) precision) =+        literal+            (   Pretty.pretty (Printf.printf "%02d" hh :: String)+            <>  ":"+            <>  Pretty.pretty (Printf.printf "%02d" mm :: String)+            <>  ":"+            <>  Pretty.pretty (Printf.printf "%02d" ss :: String)+            <>  suffix+            )+      where+        magnitude :: Integer+        magnitude = 10 ^ precision++        (ss, fraction) = truncate (seconds * fromInteger magnitude) `divMod` magnitude++        suffix+            | precision == 0 = ""+            | otherwise      = "." <> Pretty.pretty (Printf.printf "%0*d" precision fraction :: String)+    prettyPrimitiveExpression TimeShow =+        builtin "Time/show"+    prettyPrimitiveExpression TimeZone =+        builtin "TimeZone"+    prettyPrimitiveExpression (TimeZoneLiteral (Time.TimeZone minutes _ _)) =+        literal+            (   sign+            <>  Pretty.pretty (Printf.printf "%02d" _HH :: String)+            <>  ":"+            <>  Pretty.pretty (Printf.printf "%02d" _MM :: String)+            )+      where+        sign = if 0 <= minutes then "+" else "-"++        (_HH, _MM) = abs minutes `divMod` 60+    prettyPrimitiveExpression TimeZoneShow =+        builtin "TimeZone/show"     prettyPrimitiveExpression List =         builtin "List"     prettyPrimitiveExpression ListBuild =@@ -1295,6 +1440,8 @@         prettyDouble a     prettyPrimitiveExpression (TextLit a) =         prettyChunks a+    prettyPrimitiveExpression (BytesLit a) =+        prettyBytes a     prettyPrimitiveExpression (Record a) =         prettyRecord a     prettyPrimitiveExpression (RecordLit a) =@@ -1319,11 +1466,12 @@      prettyKeyValue         :: Pretty a-        => (Expr Src a -> Doc Ann)+        => (key -> Doc Ann)+        -> (Expr Src a -> Doc Ann)         -> Doc Ann-        -> KeyValue Src a+        -> KeyValue key Src a         -> (Doc Ann, Doc Ann)-    prettyKeyValue prettyValue separator (KeyValue key mSrc val) =+    prettyKeyValue prettyKey prettyValue separator (KeyValue key mSrc val) =         duplicate (Pretty.group (Pretty.flatAlt long short))       where         completion _T r =@@ -1335,7 +1483,7 @@                     _ ->                         prettySelectorExpression r -        short = prettyAnyLabels key+        short = prettyKeys prettyKey key             <>  " "             <>  separator             <>  " "@@ -1345,7 +1493,7 @@             <>  prettyValue val          long =  Pretty.align-                    (   prettyAnyLabels key+                    (   prettyKeys prettyKey key                     <>  preSeparator                     )             <>  separator@@ -1387,11 +1535,23 @@                                 <>  keyword "toMap"                                 <>  case shallowDenote val' of                                         RecordCompletion _T r ->-                                            completion _T r+                                                " "+                                            <>  completion _T r                                         _ ->    Pretty.hardline                                             <>  "    "                                             <>  prettyImportExpression_ val' +                            ShowConstructor val' ->+                                    " "+                                <>  keyword "showConstructor"+                                <>  case shallowDenote val' of+                                        RecordCompletion _T r ->+                                                " "+                                            <>  completion _T r+                                        _ ->    Pretty.hardline+                                            <>  "    "+                                            <>  prettyImportExpression_ val'+                             RecordCompletion _T r ->                                 " " <> completion _T r @@ -1422,14 +1582,43 @@      prettyRecord :: Pretty a => Map Text (RecordField Src a) -> Doc Ann     prettyRecord =-          braces-        . map (prettyKeyValue prettyExpression colon . adapt)+        ( braces+        . map (prettyKeyValue prettyAnyLabelOrSome 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 (RecordField Src a) -> Doc Ann-    prettyRecordLit = prettyRecordLike braces+    prettyRecordLit m+        | [ ("date"    , field -> d@DateLiteral{})+          , ("time"    , field -> t@TimeLiteral{})+          , ("timeZone", field -> z@TimeZoneLiteral{})+          ] <- List.sortOn fst (Map.toList m) =+              literal+                  (   prettyPrimitiveExpression d+                  <>  "T"+                  <>  prettyPrimitiveExpression t+                  <>  prettyPrimitiveExpression z+                  )+        | [ ("date"    , field -> d@DateLiteral{})+          , ("time"    , field -> t@TimeLiteral{})+          ] <- List.sortOn fst (Map.toList m) =+              literal+                  (   prettyPrimitiveExpression d+                  <>  "T"+                  <>  prettyPrimitiveExpression t+                  )+        | [ ("time"    , field -> t@TimeLiteral{})+          , ("timeZone", field -> z@TimeZoneLiteral{})+          ] <- List.sortOn fst (Map.toList m) =+              literal+                  (   prettyPrimitiveExpression t+                  <>  prettyPrimitiveExpression z+                  )+      where+        field = Dhall.Syntax.shallowDenote . recordFieldValue+    prettyRecordLit m = prettyRecordLike braces m      prettyCompletionLit :: Pretty a => Int -> Map Text (RecordField Src a) -> Doc Ann     prettyCompletionLit = prettyRecordLike . hangingBraces@@ -1451,19 +1640,23 @@                     | Var (V key' 0) <- Dhall.Syntax.shallowDenote val                     , key == key'                     , not (containsComment mSrc2) ->-                        duplicate (prettyAnyLabels [(mSrc0, key, mSrc1)])+                        duplicate (prettyKeys prettyAnyLabelOrSome [(mSrc0, key, mSrc1)])                 _ ->-                    prettyKeyValue prettyExpression equals kv+                    prettyKeyValue prettyAnyLabelOrSome prettyExpression equals kv      prettyAlternative (key, Just val) =-        prettyKeyValue prettyExpression colon (makeKeyValue (pure key) val)+        prettyKeyValue prettyAnyLabelOrSome prettyExpression colon (makeKeyValue (pure key) val)     prettyAlternative (key, Nothing) =-        duplicate (prettyAnyLabel key)+        duplicate (prettyAnyLabelOrSome key)      prettyUnion :: Pretty a => Map Text (Maybe (Expr Src a)) -> Doc Ann     prettyUnion =         angles . map prettyAlternative . Map.toList +    prettyBytes :: ByteString -> Doc Ann+    prettyBytes bytes =+        literal (Pretty.pretty ("0x\"" <> prettyBase16 bytes <> "\""))+     prettyChunks :: Pretty a => Chunks Src a -> Doc Ann     prettyChunks chunks@(Chunks a b)         | anyText (== '\n') =@@ -1497,7 +1690,7 @@          prettyMultilineText text = mconcat docs           where-            lines_ = Text.splitOn "\n" (escapeSingleQuotedText text)+            lines_ = Text.splitOn "\n" text              -- Annotate only non-empty lines so trailing whitespace can be             -- removed on empty ones.@@ -1505,8 +1698,7 @@                 (if Text.null line then id else literal)                     (Pretty.pretty line) -            docs =-                Data.List.intersperse Pretty.hardline (map prettyLine lines_)+            docs = List.intersperse Pretty.hardline (map prettyLine lines_)          prettyChunk (c, d) =                 prettyText c@@ -1526,8 +1718,10 @@ -- Chunks [("\n",TextLit (Chunks [] "\NUL\b\f"))] "\t" multilineChunks :: Chunks s a -> Chunks s a multilineChunks =-     escapeTrailingSingleQuote+     escapeSingleQuotedText+   . escapeTrailingSingleQuote    . escapeControlCharacters+   . escapeSingleQuoteBeforeInterpolation    . escapeSharedWhitespacePrefix  -- | Escape any leading whitespace shared by all lines@@ -1574,38 +1768,68 @@ -- >>> escapeControlCharacters (Chunks [] "\n\NUL\b\f\t") -- Chunks [("\n",TextLit (Chunks [] "\NUL\b\f"))] "\t" escapeControlCharacters :: Chunks s a -> Chunks s a-escapeControlCharacters (Chunks as0 b0) = Chunks as1 b1+escapeControlCharacters = splitWith (splitOnPredicate predicate)   where-    as1 = foldr f (map toChunk bs) as0+    predicate c = Data.Char.isControl c && c /= ' ' && c /= '\t' && c /= '\n' -    (bs, b1) = splitOnPredicate predicate b0+-- | Escape @'${@ correctly+--+-- See: https://github.com/dhall-lang/dhall-haskell/issues/2078+escapeSingleQuoteBeforeInterpolation :: Chunks s a -> Chunks s a+escapeSingleQuoteBeforeInterpolation = splitWith f+  where+    f text =+        case Text.splitOn "'${" text of+            -- `splitOn` should never return an empty list, but just in case…+            []     -> mempty+            t : ts -> loop t ts -    f (t0, e) chunks = map toChunk ts1 ++ (t1, e) : chunks-      where-        (ts1, t1) = splitOnPredicate predicate t0+    loop head_ tail_ =+        case tail_ of+            [] ->+                Chunks [] head_+            newHead : newTail ->+                    Chunks [ (head_, TextLit (Chunks [] "'")) ] "${"+                <>  loop newHead newTail -    predicate c = Data.Char.isControl c && c /= ' ' && c /= '\t' && c /= '\n'+{-| You can think of this as sort of like `concatMap` for `Chunks` -    toChunk (t0, t1) = (t0, TextLit (Chunks [] t1))+    Given a function that splits plain text into interpolated chunks, apply+    that function to each uninterpolated span to yield a new+    possibly-interpolated span, and flatten the results.+-}+splitWith :: (Text -> Chunks s a) -> Chunks s a -> Chunks s a+splitWith splitter (Chunks xys z) = mconcat (xys' ++ [ splitter z ])+  where+    xys' = do+        (x, y) <- xys --- | Split `Data.Text.Text` on a predicate, preserving all parts of the original--- string.+        [ splitter x, Chunks [ ("", y) ] "" ]++-- | Split `Data.Text.Text` into interpolated chunks, where all characters+-- matching the predicate are pushed into a string interpolation. -- -- >>> splitOnPredicate (== 'x') ""--- ([],"")+-- Chunks [] "" -- >>> splitOnPredicate (== 'x') " xx "--- ([(" ","xx")]," ")+-- Chunks [(" ",TextLit (Chunks [] "xx"))] " " -- >>> splitOnPredicate (== 'x') "xx"--- ([("","xx")],"")+-- Chunks [("",TextLit (Chunks [] "xx"))] "" ----- prop> \(Fun _ p) s -> let {t = Text.pack s; (as, b) = splitOnPredicate p t} in foldMap (uncurry (<>)) as <> b == t-splitOnPredicate :: (Char -> Bool) -> Text -> ([(Text, Text)], Text)-splitOnPredicate p t = case Text.break p t of-    (a, "") -> ([], a)-    (a, b)  -> case Text.span p b of-        (c, d) -> case splitOnPredicate p d of-            (e, f) -> ((a, c) : e, f)+-- prop> \(Fun _ p) s -> let {t = Text.pack s; Chunks xys z = splitOnPredicate p t} in foldMap (\(x, TextLit (Chunks [] y)) -> x <> y) xys <> z == t+splitOnPredicate :: (Char -> Bool) -> Text -> Chunks s a+splitOnPredicate predicate text+    | Text.null b =+        Chunks [] a+    | otherwise =+        Chunks ((a, TextLit (Chunks [] c)) : e) f+  where+    (a, b) = Text.break predicate text +    (c, d) = Text.span predicate b++    Chunks e f = splitOnPredicate predicate d+ -- | Escape a trailing single quote by moving it into a string interpolation -- -- Otherwise the multiline-string would end with @'''@, which would be parsed@@ -1623,13 +1847,13 @@ pretty_ :: Pretty a => a -> Text pretty_ = prettyToStrictText -data KeyValue s a = KeyValue-    { _keyValueKeys  :: NonEmpty (Maybe s, Text, Maybe s)+data KeyValue k s a = KeyValue+    { _keyValueKeys  :: NonEmpty (Maybe s, k , Maybe s)     , _keyValueSrc   :: Maybe s     , _keyValueValue :: Expr s a     } -makeKeyValue :: NonEmpty Text -> Expr s a -> KeyValue s a+makeKeyValue :: NonEmpty key -> Expr s a -> KeyValue key s a makeKeyValue keys expr = KeyValue (adapt <$> keys) Nothing expr   where     adapt key = (Nothing, key, Nothing)@@ -1637,17 +1861,18 @@ {- This utility function converts    `{ x = { y = { z = 1 } } }` to `{ x.y.z = 1 }` -}-consolidateRecordLiteral :: Map Text (RecordField Src a) -> [KeyValue Src a]+consolidateRecordLiteral+    :: Map Text (RecordField Src a) -> [KeyValue Text Src a] consolidateRecordLiteral = concatMap adapt . Map.toList   where-    adapt :: (Text, RecordField Src a) -> [KeyValue Src a]+    adapt :: (Text, RecordField Src a) -> [KeyValue Text Src a]     adapt (key, RecordField mSrc0 val mSrc1 mSrc2)         | not (containsComment mSrc2)         , RecordLit m <- e         , [ KeyValue keys mSrc2' val' ] <- concatMap adapt (Map.toList m) =             [ KeyValue (NonEmpty.cons (mSrc0, key, mSrc1) keys) mSrc2' val' ] -        | Combine (Just _) l r <- e =+        | Combine _ (Just _) l r <- e =             adapt (key, makeRecordField l) <> adapt (key, makeRecordField r)         | otherwise =             [ KeyValue (pure (mSrc0, key, mSrc1)) mSrc2 val ]@@ -1656,12 +1881,13 @@  -- | Escape a `Data.Text.Text` literal using Dhall's escaping rules for --   single-quoted @Text@-escapeSingleQuotedText :: Text -> Text-escapeSingleQuotedText inputText = outputText+escapeSingleQuotedText :: Chunks s a -> Chunks s a+escapeSingleQuotedText = splitWith f   where-    outputText = substitute "${" "''${" (substitute "''" "'''" inputText)--    substitute before after = Text.intercalate after . Text.splitOn before+    f inputText = Chunks [] outputText+      where+        outputText =+            Text.replace "${" "''${" (Text.replace "''" "'''" inputText)  {-| Escape a `Data.Text.Text` literal using Dhall's escaping rules @@ -1722,6 +1948,43 @@ layoutOpts =     Pretty.defaultLayoutOptions         { Pretty.layoutPageWidth = Pretty.AvailablePerLine 80 1.0 }++{-| Convert an expression representing a temporal value to `Data.Text.Text`, if+    possible++    This is used by downstream integrations (e.g. `dhall-json` for treating+    temporal values as strings+-}+temporalToText :: Pretty a => Expr s a -> Maybe Text+temporalToText e = case e of+    RecordLit m+        | [ ("date"    , field -> DateLiteral{})+          , ("time"    , field -> TimeLiteral{})+          , ("timeZone", field -> TimeZoneLiteral{})+          ] <- List.sortOn fst (Map.toList m) -> rendered+        | [ ("date"    , field -> DateLiteral{})+          , ("time"    , field -> TimeLiteral{})+          ] <- List.sortOn fst (Map.toList m) -> rendered+        | [ ("time"    , field -> TimeLiteral{})+          , ("timeZone", field -> TimeZoneLiteral{})+          ] <- List.sortOn fst (Map.toList m) -> rendered+    DateLiteral{} -> rendered+    TimeLiteral{} -> rendered+    TimeZoneLiteral{} -> rendered+    _ -> Nothing+  where+    field = Dhall.Syntax.shallowDenote . recordFieldValue++    rendered = Just (prettyToStrictText e)++prettyBase16 :: ByteString -> Text+prettyBase16 bytes =+    case Encoding.decodeUtf8' (Base16.encode bytes) of+        Left exception ->+            Operations.internalError+                ("prettyBase16: base16-encoded bytes could not be decoded as UTF-8 text: " <> Text.pack (Exception.displayException exception))+        Right text ->+            Text.toUpper text  {- $setup >>> import Test.QuickCheck (Fun(..))
src/Dhall/Pretty/Internal.hs-boot view
@@ -1,12 +1,28 @@ module Dhall.Pretty.Internal where -import Data.Text (Text)-import Data.Text.Prettyprint.Doc (Pretty, Doc)-import Dhall.Src (Src)+import Control.DeepSeq            (NFData)+import Data.Data                  (Data)+import Data.Text                  (Text)+import Dhall.Src                  (Src)+import Language.Haskell.TH.Syntax (Lift)+import Prettyprinter              (Doc, Pretty) -import {-# SOURCE #-} Dhall.Syntax+import                Dhall.Syntax.Const+import {-# SOURCE #-} Dhall.Syntax.Expr+import                Dhall.Syntax.Var  data Ann++data CharacterSet = ASCII | Unicode++instance Eq CharacterSet+instance Ord CharacterSet+instance Show CharacterSet+instance Data CharacterSet+instance Lift CharacterSet+instance NFData CharacterSet+instance Semigroup CharacterSet+instance Monoid CharacterSet  prettyVar :: Var -> Doc Ann 
src/Dhall/Repl.hs view
@@ -18,15 +18,13 @@     , displayException     , throwIO     )-import Control.Monad              (forM_)+import Control.Monad     (forM_) #if !(MIN_VERSION_base(4,13,0))-import Control.Monad.Fail         (MonadFail)+import Control.Monad.Fail (MonadFail) #endif-import Control.Monad.IO.Class     (MonadIO, liftIO)-import Control.Monad.State.Class  (MonadState, get, modify)-import Control.Monad.State.Strict (evalStateT)--- For the MonadFail instance for StateT.-import Control.Monad.Trans.Instances       ()+import Control.Monad.IO.Class              (MonadIO, liftIO)+import Control.Monad.State.Class           (MonadState, get, modify)+import Control.Monad.State.Strict          (evalStateT) import Data.Char                           (isSpace) import Data.List     ( dropWhileEnd@@ -47,35 +45,36 @@ import System.Directory                    (getDirectoryContents) import System.Environment                  (getEnvironment) -import qualified Control.Monad.Fail                        as Fail-import qualified Control.Monad.Trans.State.Strict          as State+import qualified Control.Monad.Fail                  as Fail+import qualified Control.Monad.Trans.State.Strict    as State import qualified Data.HashSet-import qualified Data.Text                                 as Text-import qualified Data.Text.IO                              as Text.IO-import qualified Data.Text.Prettyprint.Doc                 as Pretty-import qualified Data.Text.Prettyprint.Doc.Render.Terminal as Pretty (renderIO)+import qualified Data.Text                           as Text+import qualified Data.Text.IO                        as Text.IO import qualified Dhall import qualified Dhall.Context import qualified Dhall.Core-import qualified Dhall.Core                                as Dhall+import qualified Dhall.Core                          as Dhall     ( Expr     , Var (V)     , normalize     )-import qualified Dhall.Core                                as Expr (Expr (..))-import qualified Dhall.Import                              as Dhall-import qualified Dhall.Map                                 as Map-import qualified Dhall.Parser                              as Dhall-import qualified Dhall.Parser.Token                        as Parser.Token+import qualified Dhall.Core                          as Expr (Expr (..))+import qualified Dhall.Import                        as Dhall+import qualified Dhall.Map                           as Map+import qualified Dhall.Parser                        as Dhall+import qualified Dhall.Parser.Expression             as Parser.Expression import qualified Dhall.Pretty import qualified Dhall.Pretty.Internal-import qualified Dhall.TypeCheck                           as Dhall-import qualified Dhall.Version                             as Meta+import qualified Dhall.Syntax                        as Syntax+import qualified Dhall.TypeCheck                     as Dhall+import qualified Dhall.Version                       as Meta+import qualified Prettyprinter                       as Pretty+import qualified Prettyprinter.Render.Terminal       as Pretty (renderIO) import qualified System.Console.ANSI-import qualified System.Console.Haskeline.Completion       as Haskeline-import qualified System.Console.Repline                    as Repline+import qualified System.Console.Haskeline.Completion as Haskeline+import qualified System.Console.Repline              as Repline import qualified System.IO-import qualified Text.Megaparsec                           as Megaparsec+import qualified Text.Megaparsec                     as Megaparsec  #if MIN_VERSION_haskeline(0,8,0) import qualified Control.Monad.Catch@@ -236,31 +235,51 @@   | otherwise   = Left (trim str) -addBinding :: ( MonadFail m, MonadIO m, MonadState Env m ) => Either String (String, String) -> m ()-addBinding (Right (k, src)) = do-  varName <- case Megaparsec.parse (unParser Parser.Token.label) "(input)" (Text.pack k) of-      Left   _      -> Fail.fail "Invalid variable name"-      Right varName -> return varName+addBinding :: ( MonadFail m, MonadIO m, MonadState Env m ) => String -> m ()+addBinding string = do+  let parseBinding =+          Parser.Expression.letBinding+              (Parser.Expression.parsers+                  (Megaparsec.try Parser.Expression.import_)+              ) -  loaded <- parseAndLoad src+  let input = "let " <> Text.pack string -  t <- typeCheck loaded+  Syntax.Binding{ variable, annotation, value } <- case Megaparsec.parse (unParser parseBinding) "(input)" input of+      Left  _       -> Fail.fail ":let should be of the form `:let x [: T] = y`"+      Right binding -> return binding -  expr <- normalize loaded+  (resolved, bindingType) <- case annotation of+      Just (_, unresolvedType) -> do+          let annotated = Syntax.Annot value unresolvedType +          resolved <- liftIO (Dhall.load annotated)++          _ <- typeCheck resolved++          bindingType <- liftIO (Dhall.load unresolvedType)++          return (resolved, bindingType)+      _ -> do+          resolved <- liftIO (Dhall.load value)++          bindingType <- typeCheck resolved++          return (resolved, bindingType)++  bindingExpr <- normalize resolved+   modify     ( \e ->         e { envBindings =               Dhall.Context.insert-                varName-                Binding { bindingType = t, bindingExpr = expr }+                variable+                Binding{ bindingType, bindingExpr }                 ( envBindings e )           }     ) -  output ( Expr.Annot ( Expr.Var ( Dhall.V varName 0 ) ) t )--addBinding _ = Fail.fail ":let should be of the form `:let x = y`"+  output (Expr.Annot (Expr.Var (Dhall.V variable 0)) bindingType)  clearBindings :: (MonadFail m, MonadState Env m) => String -> m () clearBindings _ = modify adapt@@ -275,7 +294,8 @@    normalizedExpression <- normalize loadedExpression -  writeOutputHandle $ hashExpressionToCode normalizedExpression+  writeOutputHandle+    (hashExpressionToCode (Dhall.Core.alphaNormalize normalizedExpression))  saveFilePrefix :: FilePath saveFilePrefix = ".dhall-repl"@@ -478,7 +498,7 @@       "let"       "IDENTIFIER = EXPRESSION"       "Assign an expression to a variable"-      (dontCrash . addBinding . parseAssignment)+      (dontCrash . addBinding)   , HelpOption       "clear"       ""
src/Dhall/Schemas.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE DeriveAnyClass    #-}-{-# LANGUAGE OverloadedLists   #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards   #-} @@ -17,62 +16,65 @@  import Control.Applicative (empty) import Control.Exception   (Exception)+import Data.Maybe          (fromMaybe) import Data.Text           (Text) import Data.Void           (Void) import Dhall.Crypto        (SHA256Digest) import Dhall.Map           (Map)-import Dhall.Pretty        (CharacterSet (..))+import Dhall.Pretty        (CharacterSet (..), detectCharacterSet) import Dhall.Src           (Src) import Dhall.Syntax        (Expr (..), Import, Var (..)) import Dhall.Util     ( Censor (..)-    , CheckFailed (..)     , Header (..)     , Input (..)+    , MultipleCheckFailed (..)     , OutputMode (..)     ) -import qualified Control.Exception                         as Exception+import qualified Control.Exception                  as Exception import qualified Data.Map-import qualified Data.Maybe                                as Maybe-import qualified Data.Text.IO                              as Text.IO-import qualified Data.Text.Prettyprint.Doc                 as Pretty-import qualified Data.Text.Prettyprint.Doc.Render.Terminal as Pretty.Terminal-import qualified Data.Text.Prettyprint.Doc.Render.Text     as Pretty.Text-import qualified Data.Void                                 as Void-import qualified Dhall.Core                                as Core-import qualified Dhall.Import                              as Import-import qualified Dhall.Map                                 as Map-import qualified Dhall.Normalize                           as Normalize-import qualified Dhall.Optics                              as Optics-import qualified Dhall.Parser                              as Parser+import qualified Data.Maybe                         as Maybe+import qualified Data.Text.IO                       as Text.IO+import qualified Data.Void                          as Void+import qualified Dhall.Core                         as Core+import qualified Dhall.Import                       as Import+import qualified Dhall.Map                          as Map+import qualified Dhall.Normalize                    as Normalize+import qualified Dhall.Parser                       as Parser import qualified Dhall.Pretty-import qualified Dhall.Substitution                        as Substitution-import qualified Dhall.Syntax                              as Syntax-import qualified Dhall.TypeCheck                           as TypeCheck-import qualified Dhall.Util                                as Util-import qualified System.AtomicWrite.Writer.LazyText        as AtomicWrite-import qualified System.Console.ANSI                       as ANSI-import qualified System.IO                                 as IO+import qualified Dhall.Substitution                 as Substitution+import qualified Dhall.Syntax                       as Syntax+import qualified Dhall.TypeCheck                    as TypeCheck+import qualified Dhall.Util                         as Util+import qualified Lens.Micro                         as Lens+import qualified Prettyprinter                      as Pretty+import qualified Prettyprinter.Render.Terminal      as Pretty.Terminal+import qualified Prettyprinter.Render.Text          as Pretty.Text+import qualified System.AtomicWrite.Writer.LazyText as AtomicWrite+import qualified System.Console.ANSI                as ANSI+import qualified System.IO                          as IO  -- | Arguments to the @rewrite-with-schemas@ subcommand data Schemas = Schemas-    { characterSet :: CharacterSet-    , censor       :: Censor-    , input        :: Input-    , outputMode   :: OutputMode-    , schemas      :: Text+    { chosenCharacterSet :: Maybe CharacterSet+    , censor             :: Censor+    , input              :: Input+    , outputMode         :: OutputMode+    , schemas            :: Text     }  -- | Implementation of the @dhall rewrite-with-schemas@ subcommand schemasCommand :: Schemas -> IO () schemasCommand Schemas{..} = do-    originalText <- case input of-        InputFile file -> Text.IO.readFile file-        StandardInput  -> Text.IO.getContents+    (inputName, originalText) <- case input of+        InputFile file -> (,) file <$> Text.IO.readFile file+        StandardInput  -> (,) "(input)" <$> Text.IO.getContents -    (Header header, expression) <- Util.getExpressionAndHeaderFromStdinText censor originalText+    (Header header, expression) <- Util.getExpressionAndHeaderFromStdinText censor inputName originalText +    let characterSet = fromMaybe (detectCharacterSet expression) chosenCharacterSet+     schemasRecord <- Core.throws (Parser.exprFromText "(schemas)" schemas)      schemasExpression <- rewriteWithSchemas schemasRecord expression@@ -112,8 +114,10 @@                      let modified = "rewritten" -                    Exception.throwIO CheckFailed{..}+                    let inputs = pure input +                    Exception.throwIO MultipleCheckFailed{..}+ decodeSchema :: Expr s Void -> Maybe (Expr s Void, Map Text (Expr s Void)) decodeSchema (RecordLit m)         | Just  _Type               <- Core.recordFieldValue <$> Map.lookup "Type" m@@ -191,7 +195,7 @@      let rewrittenExpression :: Expr Src Import         rewrittenExpression =-            fmap Void.absurd (Optics.transformOf Syntax.subExpressions schemasRewrite normalizedExpression)+            fmap Void.absurd (Lens.transformOf Syntax.subExpressions schemasRewrite normalizedExpression)      if Normalize.freeIn (V "schemas" 0) rewrittenExpression         then return (Let (Syntax.makeBinding "schemas" _schemas) rewrittenExpression)
src/Dhall/Src.hs view
@@ -15,10 +15,10 @@ import Control.DeepSeq            (NFData) import Data.Data                  (Data) import Data.Text                  (Text)-import Data.Text.Prettyprint.Doc  (Pretty (..)) import GHC.Generics               (Generic) import Instances.TH.Lift          () import Language.Haskell.TH.Syntax (Lift (..))+import Prettyprinter              (Pretty (..)) import Text.Megaparsec            (SourcePos (SourcePos), mkPos, unPos)  import {-# SOURCE #-} qualified Dhall.Util
src/Dhall/Syntax.hs view
@@ -1,1448 +1,31 @@-{-# LANGUAGE DeriveAnyClass     #-}-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE DeriveGeneric      #-}-{-# LANGUAGE DeriveLift         #-}-{-# LANGUAGE DeriveTraversable  #-}-{-# LANGUAGE LambdaCase         #-}-{-# LANGUAGE OverloadedLists    #-}-{-# LANGUAGE OverloadedStrings  #-}-{-# LANGUAGE PatternSynonyms    #-}-{-# LANGUAGE RankNTypes         #-}-{-# LANGUAGE RecordWildCards    #-}-{-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE UnicodeSyntax      #-}--{-| This module contains the core syntax types and optics for them.--'reservedIdentifiers', 'denote' and friends are included because they are-involved in a dependency circle with "Dhall.Pretty.Internal".--}--module Dhall.Syntax (-    -- * 'Expr'-      Const(..)-    , Var(..)-    , Binding(..)-    , makeBinding-    , Chunks(..)-    , DhallDouble(..)-    , PreferAnnotation(..)-    , Expr(..)-    , RecordField(..)-    , makeRecordField-    , FunctionBinding(..)-    , makeFunctionBinding-    , FieldSelection(..)-    , makeFieldSelection--    -- ** 'Let'-blocks-    , MultiLet(..)-    , multiLet-    , wrapInLets--    -- ** Optics-    , subExpressions-    , unsafeSubExpressions-    , chunkExprs-    , bindingExprs-    , recordFieldExprs-    , functionBindingExprs--    -- ** Handling 'Note's-    , denote-    , renote-    , shallowDenote--    -- * 'Import'-    , Directory(..)-    , File(..)-    , FilePrefix(..)-    , Import(..)-    , ImportHashed(..)-    , ImportMode(..)-    , ImportType(..)-    , URL(..)-    , Scheme(..)-    , pathCharacter--    -- * Reserved identifiers-    , reservedIdentifiers-    , reservedKeywords--    -- * `Data.Text.Text` manipulation-    , toDoubleQuoted-    , longestSharedWhitespacePrefix-    , linesLiteral-    , unlinesLiteral--    -- * Desugaring-    , desugarWith--    -- * Utilities-    , internalError-    -- `shift` should really be in `Dhall.Normalize`, but it's here to avoid a-    -- module cycle-    , shift-    ) where--import Control.DeepSeq            (NFData)-import Data.Bifunctor             (Bifunctor (..))-import Data.Bits                  (xor)-import Data.Data                  (Data)-import Data.Foldable-import Data.HashSet               (HashSet)-import Data.List.NonEmpty         (NonEmpty (..))-import Data.Sequence              (Seq)-import Data.String                (IsString (..))-import Data.Text                  (Text)-import Data.Text.Prettyprint.Doc  (Doc, Pretty)-import Data.Traversable           ()-import Data.Void                  (Void)-import Dhall.Map                  (Map)-import {-# SOURCE #-} Dhall.Pretty.Internal-import Dhall.Set                  (Set)-import Dhall.Src                  (Src (..))-import GHC.Generics               (Generic)-import Instances.TH.Lift          ()-import Language.Haskell.TH.Syntax (Lift)-import Numeric.Natural            (Natural)-import Unsafe.Coerce              (unsafeCoerce)--import qualified Control.Monad-import qualified Data.HashSet-import qualified Data.List.NonEmpty        as NonEmpty-import qualified Data.Text-import qualified Data.Text.Prettyprint.Doc as Pretty-import qualified Dhall.Crypto-import qualified Dhall.Optics              as Optics-import qualified Lens.Family               as Lens-import qualified Network.URI               as URI---- $setup--- >>> import Dhall.Binary () -- For the orphan instance for `Serialise (Expr Void Import)`--{-| Constants for a pure type system--    The axioms are:--> ⊦ Type : Kind-> ⊦ Kind : Sort--    ... and the valid rule pairs are:--> ⊦ Type ↝ Type : Type  -- Functions from terms to terms (ordinary functions)-> ⊦ Kind ↝ Type : Type  -- Functions from types to terms (type-polymorphic functions)-> ⊦ Sort ↝ Type : Type  -- Functions from kinds to terms-> ⊦ Kind ↝ Kind : Kind  -- Functions from types to types (type-level functions)-> ⊦ Sort ↝ Kind : Sort  -- Functions from kinds to types (kind-polymorphic functions)-> ⊦ Sort ↝ Sort : Sort  -- Functions from kinds to kinds (kind-level functions)--    Note that Dhall does not support functions from terms to types and therefore-    Dhall is not a dependently typed language--}-data Const = Type | Kind | Sort-    deriving (Show, Eq, Ord, Data, Bounded, Enum, Generic, Lift, NFData)--instance Pretty Const where-    pretty = Pretty.unAnnotate . prettyConst--{-| Label for a bound variable--    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-    nearest bound variable and the index increases by one for each bound-    variable of the same name going outward.  The following diagram may help:-->                               ┌──refers to──┐->                               │             │->                               v             │-> λ(x : Type) → λ(y : Type) → λ(x : Type) → x@0->-> ┌─────────────────refers to─────────────────┐-> │                                           │-> v                                           │-> λ(x : Type) → λ(y : Type) → λ(x : Type) → x@1--    This `Int` behaves like a De Bruijn index in the special case where all-    variables have the same name.--    You can optionally omit the index if it is @0@:-->                               ┌─refers to─┐->                               │           │->                               v           │-> λ(x : Type) → λ(y : Type) → λ(x : Type) → x--    Zero indices are omitted when pretty-printing @Var@s and non-zero indices-    appear as a numeric suffix.--}-data Var = V Text !Int-    deriving (Data, Generic, Eq, Ord, Show, Lift, NFData)--instance IsString Var where-    fromString str = V (fromString str) 0--instance Pretty Var where-    pretty = Pretty.unAnnotate . prettyVar--{- | Record the binding part of a @let@ expression.--For example,--> let {- A -} x {- B -} : {- C -} Bool = {- D -} True in x--will be instantiated as follows:--* @bindingSrc0@ corresponds to the @A@ comment.-* @variable@ is @"x"@-* @bindingSrc1@ corresponds to the @B@ comment.-* @annotation@ is 'Just' a pair, corresponding to the @C@ comment and @Bool@.-* @bindingSrc2@ corresponds to the @D@ comment.-* @value@ corresponds to @True@.--}-data Binding s a = Binding-    { bindingSrc0 :: Maybe s-    , variable    :: Text-    , bindingSrc1 :: Maybe s-    , annotation  :: Maybe (Maybe s, Expr s a)-    , bindingSrc2 :: Maybe s-    , value       :: Expr s a-    } deriving (Data, Eq, Foldable, Functor, Generic, Lift, NFData, Ord, Show, Traversable)--instance Bifunctor Binding where-    first k (Binding src0 a src1 b src2 c) =-        Binding (fmap k src0) a (fmap k src1) (fmap adapt0 b) (fmap k src2) (first k c)-      where-        adapt0 (src3, d) = (fmap k src3, first k d)--    second = fmap--{-| Construct a 'Binding' with no source information and no type annotation.--}-makeBinding :: Text -> Expr s a -> Binding s a-makeBinding name = Binding Nothing name Nothing Nothing Nothing---- | This wrapper around 'Prelude.Double' exists for its 'Eq' instance which is--- defined via the binary encoding of Dhall @Double@s.-newtype DhallDouble = DhallDouble { getDhallDouble :: Double }-    deriving (Show, Data, Lift, NFData, Generic)---- | This instance satisfies all the customary 'Eq' laws except substitutivity.------ In particular:------ >>> nan = DhallDouble (0/0)--- >>> nan == nan--- True------ This instance is also consistent with with the binary encoding of Dhall @Double@s:------ >>> toBytes n = Dhall.Binary.encodeExpression (DoubleLit n :: Expr Void Import)------ prop> \a b -> (a == b) == (toBytes a == toBytes b)-instance Eq DhallDouble where-    DhallDouble a == DhallDouble b-        | isNaN a && isNaN b                      = True-        | isNegativeZero a `xor` isNegativeZero b = False-        | otherwise                               = a == b---- | This instance relies on the 'Eq' instance for 'DhallDouble' but cannot--- satisfy the customary 'Ord' laws when @NaN@ is involved.-instance Ord DhallDouble where-    compare a@(DhallDouble a') b@(DhallDouble b') =-        if a == b-            then EQ-            else compare a' b'---- | The body of an interpolated @Text@ literal-data Chunks s a = Chunks [(Text, Expr s a)] Text-    deriving (Functor, Foldable, Generic, Traversable, Show, Eq, Ord, Data, Lift, NFData)--instance Semigroup (Chunks s a) where-    Chunks xysL zL <> Chunks         []    zR =-        Chunks xysL (zL <> zR)-    Chunks xysL zL <> Chunks ((x, y):xysR) zR =-        Chunks (xysL ++ (zL <> x, y):xysR) zR--instance Monoid (Chunks s a) where-    mempty = Chunks [] mempty--instance IsString (Chunks s a) where-    fromString str = Chunks [] (fromString str)---- | Used to record the origin of a @//@ operator (i.e. from source code or a--- product of desugaring)-data PreferAnnotation s a-    = PreferFromSource-    | PreferFromWith (Expr s a)-      -- ^ Stores the original @with@ expression-    | PreferFromCompletion-    deriving (Data, Eq, Foldable, Functor, Generic, Lift, NFData, Ord, Show, Traversable)--instance Bifunctor PreferAnnotation where-    first _  PreferFromSource      = PreferFromSource-    first f (PreferFromWith e    ) = PreferFromWith (first f e)-    first _  PreferFromCompletion  = PreferFromCompletion--    second = fmap--{-| Record the field of a record-type and record-literal expression.-    The reason why we use the same ADT for both of them is because they store-    the same information.--For example,--> { {- A -} x {- B -} : {- C -} T }--... or--> { {- A -} x {- B -} = {- C -} T }--will be instantiated as follows:--* @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.--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-    { 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 e = RecordField Nothing e Nothing Nothing---instance Bifunctor RecordField where-    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 `Note`-      constructor or inline within another constructor, like `Let`)-    * If @s = `Void`@ then the code has no `Src` spans--    The @a@ type parameter is used to track the presence or absence of imports--    * If @a = `Import`@ then the code may contain unresolved `Import`s-    * If @a = `Void`@ then the code has no `Import`s--}-data Expr s a-    -- | > Const c                                  ~  c-    = Const Const-    -- | > Var (V x 0)                              ~  x-    --   > Var (V x n)                              ~  x@n-    | Var Var-    -- | > 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)-    -- | > App f a                                  ~  f a-    | App (Expr s a) (Expr s a)-    -- | > Let (Binding _ x _  Nothing  _ r) e      ~  let x     = r in e-    --   > Let (Binding _ x _ (Just t ) _ r) e      ~  let x : t = r in e-    ---    -- The difference between-    ---    -- > let x = a    let y = b in e-    ---    -- and-    ---    -- > let x = a in let y = b in e-    ---    -- is only an additional 'Note' around @'Let' "y" …@ in the second-    -- example.-    ---    -- See 'MultiLet' for a representation of let-blocks that mirrors the-    -- source code more closely.-    | Let (Binding s a) (Expr s a)-    -- | > Annot x t                                ~  x : t-    | Annot (Expr s a) (Expr s a)-    -- | > Bool                                     ~  Bool-    | Bool-    -- | > BoolLit b                                ~  b-    | BoolLit Bool-    -- | > BoolAnd x y                              ~  x && y-    | BoolAnd (Expr s a) (Expr s a)-    -- | > BoolOr  x y                              ~  x || y-    | BoolOr  (Expr s a) (Expr s a)-    -- | > BoolEQ  x y                              ~  x == y-    | BoolEQ  (Expr s a) (Expr s a)-    -- | > BoolNE  x y                              ~  x != y-    | BoolNE  (Expr s a) (Expr s a)-    -- | > BoolIf x y z                             ~  if x then y else z-    | BoolIf (Expr s a) (Expr s a) (Expr s a)-    -- | > Natural                                  ~  Natural-    | Natural-    -- | > NaturalLit n                             ~  n-    | NaturalLit Natural-    -- | > NaturalFold                              ~  Natural/fold-    | NaturalFold-    -- | > NaturalBuild                             ~  Natural/build-    | NaturalBuild-    -- | > NaturalIsZero                            ~  Natural/isZero-    | NaturalIsZero-    -- | > NaturalEven                              ~  Natural/even-    | NaturalEven-    -- | > NaturalOdd                               ~  Natural/odd-    | NaturalOdd-    -- | > NaturalToInteger                         ~  Natural/toInteger-    | NaturalToInteger-    -- | > NaturalShow                              ~  Natural/show-    | NaturalShow-    -- | > NaturalSubtract                          ~  Natural/subtract-    | NaturalSubtract-    -- | > NaturalPlus x y                          ~  x + y-    | NaturalPlus (Expr s a) (Expr s a)-    -- | > NaturalTimes x y                         ~  x * y-    | NaturalTimes (Expr s a) (Expr s a)-    -- | > Integer                                  ~  Integer-    | Integer-    -- | > IntegerLit n                             ~  ±n-    | IntegerLit Integer-    -- | > IntegerClamp                             ~  Integer/clamp-    | IntegerClamp-    -- | > IntegerNegate                            ~  Integer/negate-    | IntegerNegate-    -- | > IntegerShow                              ~  Integer/show-    | IntegerShow-    -- | > IntegerToDouble                          ~  Integer/toDouble-    | IntegerToDouble-    -- | > Double                                   ~  Double-    | Double-    -- | > DoubleLit n                              ~  n-    | DoubleLit DhallDouble-    -- | > DoubleShow                               ~  Double/show-    | DoubleShow-    -- | > Text                                     ~  Text-    | Text-    -- | > TextLit (Chunks [(t1, e1), (t2, e2)] t3) ~  "t1${e1}t2${e2}t3"-    | TextLit (Chunks s a)-    -- | > TextAppend x y                           ~  x ++ y-    | TextAppend (Expr s a) (Expr s a)-    -- | > TextReplace                              ~ Text/replace-    | TextReplace-    -- | > TextShow                                 ~  Text/show-    | TextShow-    -- | > List                                     ~  List-    | List-    -- | > ListLit (Just t ) []                     ~  [] : t-    --   > ListLit  Nothing  [x, y, z]              ~  [x, y, z]-    ---    --   Invariant: A non-empty list literal is always represented as-    --   @ListLit Nothing xs@.-    ---    --   When an annotated, non-empty list literal is parsed, it is represented-    --   as-    ---    --   > Annot (ListLit Nothing [x, y, z]) t      ~ [x, y, z] : t--    -- Eventually we should have separate constructors for empty and non-empty-    -- list literals. For now it's easier to check the invariant in @infer@.-    -- See https://github.com/dhall-lang/dhall-haskell/issues/1359#issuecomment-537087234.-    | ListLit (Maybe (Expr s a)) (Seq (Expr s a))-    -- | > ListAppend x y                           ~  x # y-    | ListAppend (Expr s a) (Expr s a)-    -- | > ListBuild                                ~  List/build-    | ListBuild-    -- | > ListFold                                 ~  List/fold-    | ListFold-    -- | > ListLength                               ~  List/length-    | ListLength-    -- | > ListHead                                 ~  List/head-    | ListHead-    -- | > ListLast                                 ~  List/last-    | ListLast-    -- | > ListIndexed                              ~  List/indexed-    | ListIndexed-    -- | > ListReverse                              ~  List/reverse-    | ListReverse-    -- | > Optional                                 ~  Optional-    | Optional-    -- | > Some e                                   ~  Some e-    | Some (Expr s a)-    -- | > None                                     ~  None-    | None-    -- | > Record [ (k1, RecordField _ t1)          ~  { k1 : t1, k2 : t1 }-    --   >        , (k2, RecordField _ t2)-    --   >        ]-    | Record    (Map Text (RecordField s a))-    -- | > RecordLit [ (k1, RecordField _ v1)       ~  { k1 = v1, k2 = v2 }-    --   >           , (k2, RecordField _ v2)-    --   >           ]-    | RecordLit (Map Text (RecordField s a))-    -- | > Union        [(k1, Just t1), (k2, Nothing)] ~  < k1 : t1 | k2 >-    | Union     (Map Text (Maybe (Expr s a)))-    -- | > Combine Nothing x y                      ~  x ∧ y-    ---    -- The first field is a `Just` when the `Combine` operator is introduced-    -- as a result of desugaring duplicate record fields:-    ---    --   > RecordLit [ ( k                          ~ { k = x, k = y }-    --   >           , RecordField-    --   >              _-    --   >              (Combine (Just k) x y)-    --   >            )]-    | Combine (Maybe Text) (Expr s a) (Expr s a)-    -- | > CombineTypes x y                         ~  x ⩓ y-    | CombineTypes (Expr s a) (Expr s a)-    -- | > Prefer False x y                         ~  x ⫽ y-    ---    -- The first field is a `True` when the `Prefer` operator is introduced as a-    -- result of desugaring a @with@ expression-    | Prefer (PreferAnnotation s a) (Expr s a) (Expr s a)-    -- | > RecordCompletion x y                     ~  x::y-    | RecordCompletion (Expr s a) (Expr s a)-    -- | > Merge x y (Just t )                      ~  merge x y : t-    --   > Merge x y  Nothing                       ~  merge x y-    | Merge (Expr s a) (Expr s a) (Maybe (Expr s a))-    -- | > ToMap x (Just t)                         ~  toMap x : t-    --   > ToMap x  Nothing                         ~  toMap x-    | ToMap (Expr s a) (Maybe (Expr s a))-    -- | > 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))-    -- | > Assert e                                 ~  assert : e-    | Assert (Expr s a)-    -- | > Equivalent x y                           ~  x ≡ y-    | Equivalent (Expr s a) (Expr s a)-    -- | > With x y e                               ~  x with y = e-    | With (Expr s a) (NonEmpty Text) (Expr s a)-    -- | > Note s x                                 ~  e-    | Note s (Expr s a)-    -- | > ImportAlt                                ~  e1 ? e2-    | ImportAlt (Expr s a) (Expr s a)-    -- | > Embed import                             ~  import-    | Embed a-    deriving (Foldable, Generic, Traversable, Show, Data, Lift, NFData)--- NB: If you add a constructor to Expr, please also update the Arbitrary--- instance in Dhall.Test.QuickCheck.---- | This instance encodes what the Dhall standard calls an \"exact match\"--- between two expressions.------ Note that------ >>> nan = DhallDouble (0/0)--- >>> DoubleLit nan == DoubleLit nan--- True-deriving instance (Eq s, Eq a) => Eq (Expr s a)---- | Note that this 'Ord' instance inherits `DhallDouble`'s defects.-deriving instance (Ord s, Ord a) => Ord (Expr s a)---- This instance is hand-written due to the fact that deriving--- it does not give us an INLINABLE pragma. We annotate this fmap--- implementation with this pragma below to allow GHC to, possibly,--- inline the implementation for performance improvements.-instance Functor (Expr s) where-  fmap f (Embed a) = Embed (f a)-  fmap f (Let b e2) = Let (fmap f b) (fmap f e2)-  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 #-}--instance Applicative (Expr s) where-    pure = Embed--    (<*>) = Control.Monad.ap--instance Monad (Expr s) where-    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-        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 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-    first k (Note a b   ) = Note (k a) (first k b)-    first _ (Embed a    ) = Embed a-    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--instance IsString (Expr s a) where-    fromString str = Var (fromString str)---- | Generates a syntactically valid Dhall program-instance Pretty a => Pretty (Expr s a) where-    pretty = Pretty.unAnnotate . prettyExpr--{--Instead of converting explicitly between 'Expr's and 'MultiLet', it might-be nicer to use a pattern synonym:--> pattern MultiLet' :: NonEmpty (Binding s a) -> Expr s a -> Expr s a-> pattern MultiLet' as b <- (multiLetFromExpr -> Just (MultiLet as b)) where->   MultiLet' as b = wrapInLets as b->-> multiLetFromExpr :: Expr s a -> Maybe (MultiLet s a)-> multiLetFromExpr = \case->     Let x mA a b -> Just (multiLet x mA a b)->     _ -> Nothing--This works in principle, but GHC as of v8.8.1 doesn't handle it well:-https://gitlab.haskell.org/ghc/ghc/issues/17096--This should be fixed by GHC-8.10, so it might be worth revisiting then.--}--{-| Generate a 'MultiLet' from the contents of a 'Let'.--    In the resulting @'MultiLet' bs e@, @e@ is guaranteed not to be a 'Let',-    but it might be a @('Note' … ('Let' …))@.--    Given parser output, 'multiLet' consolidates @let@s that formed a-    let-block in the original source.--}-multiLet :: Binding s a -> Expr s a -> MultiLet s a-multiLet b0 = \case-    Let b1 e1 ->-        let MultiLet bs e = multiLet b1 e1-        in  MultiLet (NonEmpty.cons b0 bs) e-    e -> MultiLet (b0 :| []) e--{-| Wrap let-'Binding's around an 'Expr'.--'wrapInLets' can be understood as an inverse for 'multiLet':--> let MultiLet bs e1 = multiLet b e0->-> wrapInLets bs e1 == Let b e0--}-wrapInLets :: Foldable f => f (Binding s a) -> Expr s a -> Expr s a-wrapInLets bs e = foldr Let e bs--{-| This type represents 1 or more nested `Let` bindings that have been-    coalesced together for ease of manipulation--}-data MultiLet s a = MultiLet (NonEmpty (Binding s a)) (Expr s a)---- | A traversal over the immediate sub-expressions of an expression.-subExpressions-    :: Applicative f => (Expr s a -> f (Expr s a)) -> Expr s a -> f (Expr s a)-subExpressions _ (Embed a) = pure (Embed a)-subExpressions f (Note a b) = Note a <$> f b-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 #-}--{-| An internal utility used to implement transformations that require changing-    one of the type variables of the `Expr` type--    This utility only works because the implementation is partial, not-    handling the `Let`, `Note`, or `Embed` cases, which need to be handled by-    the caller.--}-unsafeSubExpressions-    :: 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 (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-unsafeSubExpressions _ Bool = pure Bool-unsafeSubExpressions _ (BoolLit b) = pure (BoolLit b)-unsafeSubExpressions f (BoolAnd a b) = BoolAnd <$> f a <*> f b-unsafeSubExpressions f (BoolOr a b) = BoolOr <$> f a <*> f b-unsafeSubExpressions f (BoolEQ a b) = BoolEQ <$> f a <*> f b-unsafeSubExpressions f (BoolNE a b) = BoolNE <$> f a <*> f b-unsafeSubExpressions f (BoolIf a b c) = BoolIf <$> f a <*> f b <*> f c-unsafeSubExpressions _ Natural = pure Natural-unsafeSubExpressions _ (NaturalLit n) = pure (NaturalLit n)-unsafeSubExpressions _ NaturalFold = pure NaturalFold-unsafeSubExpressions _ NaturalBuild = pure NaturalBuild-unsafeSubExpressions _ NaturalIsZero = pure NaturalIsZero-unsafeSubExpressions _ NaturalEven = pure NaturalEven-unsafeSubExpressions _ NaturalOdd = pure NaturalOdd-unsafeSubExpressions _ NaturalToInteger = pure NaturalToInteger-unsafeSubExpressions _ NaturalShow = pure NaturalShow-unsafeSubExpressions _ NaturalSubtract = pure NaturalSubtract-unsafeSubExpressions f (NaturalPlus a b) = NaturalPlus <$> f a <*> f b-unsafeSubExpressions f (NaturalTimes a b) = NaturalTimes <$> f a <*> f b-unsafeSubExpressions _ Integer = pure Integer-unsafeSubExpressions _ (IntegerLit n) = pure (IntegerLit n)-unsafeSubExpressions _ IntegerClamp = pure IntegerClamp-unsafeSubExpressions _ IntegerNegate = pure IntegerNegate-unsafeSubExpressions _ IntegerShow = pure IntegerShow-unsafeSubExpressions _ IntegerToDouble = pure IntegerToDouble-unsafeSubExpressions _ Double = pure Double-unsafeSubExpressions _ (DoubleLit n) = pure (DoubleLit n)-unsafeSubExpressions _ DoubleShow = pure DoubleShow-unsafeSubExpressions _ Text = pure Text-unsafeSubExpressions f (TextLit chunks) =-    TextLit <$> chunkExprs f chunks-unsafeSubExpressions f (TextAppend a b) = TextAppend <$> f a <*> f b-unsafeSubExpressions _ TextReplace = pure TextReplace-unsafeSubExpressions _ TextShow = pure TextShow-unsafeSubExpressions _ List = pure List-unsafeSubExpressions f (ListLit a b) = ListLit <$> traverse f a <*> traverse f b-unsafeSubExpressions f (ListAppend a b) = ListAppend <$> f a <*> f b-unsafeSubExpressions _ ListBuild = pure ListBuild-unsafeSubExpressions _ ListFold = pure ListFold-unsafeSubExpressions _ ListLength = pure ListLength-unsafeSubExpressions _ ListHead = pure ListHead-unsafeSubExpressions _ ListLast = pure ListLast-unsafeSubExpressions _ ListIndexed = pure ListIndexed-unsafeSubExpressions _ ListReverse = pure ListReverse-unsafeSubExpressions _ Optional = pure Optional-unsafeSubExpressions f (Some a) = Some <$> f a-unsafeSubExpressions _ None = pure None-unsafeSubExpressions f (Union a) = Union <$> traverse (traverse f) a-unsafeSubExpressions f (Combine a b c) = Combine a <$> f b <*> f c-unsafeSubExpressions f (CombineTypes a b) = CombineTypes <$> f a <*> f b-unsafeSubExpressions f (Prefer a b c) = Prefer <$> a' <*> f b <*> f c-  where-    a' = case a of-        PreferFromSource     -> pure PreferFromSource-        PreferFromWith d     -> PreferFromWith <$> f d-        PreferFromCompletion -> pure PreferFromCompletion-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 (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-unsafeSubExpressions f (With a b c) = With <$> f a <*> pure b <*> f c-unsafeSubExpressions f (ImportAlt l r) = ImportAlt <$> f l <*> f r-unsafeSubExpressions _ (Let {}) = unhandledConstructor "Let"-unsafeSubExpressions _ (Note {}) = unhandledConstructor "Note"-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-unhandledConstructor constructor =-    internalError-        (   "Dhall.Syntax.unsafeSubExpressions: Unhandled "-        <>  constructor-        <>  " construtor"-        )--{-| Traverse over the immediate 'Expr' children in a 'Binding'.--}-bindingExprs-  :: (Applicative f)-  => (Expr s a -> f (Expr s b))-  -> Binding s a -> f (Binding s b)-bindingExprs f (Binding s0 n s1 t s2 v) =-  Binding-    <$> pure s0-    <*> pure n-    <*> pure s1-    <*> traverse (traverse f) t-    <*> pure s2-    <*> f v-{-# INLINABLE bindingExprs #-}--{-| Traverse over the immediate 'Expr' children in a 'RecordField'.--}-recordFieldExprs-    :: Applicative f-    => (Expr s a -> f (Expr s b))-    -> RecordField s a -> f (RecordField s b)-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-  => (Expr s a -> f (Expr t b))-  -> Chunks s a -> f (Chunks t b)-chunkExprs f (Chunks chunks final) =-  flip Chunks final <$> traverse (traverse f) chunks-{-# INLINABLE chunkExprs #-}--{-| Internal representation of a directory that stores the path components in-    reverse order--    In other words, the directory @\/foo\/bar\/baz@ is encoded as-    @Directory { components = [ "baz", "bar", "foo" ] }@--}-newtype Directory = Directory { components :: [Text] }-    deriving (Eq, Generic, Ord, Show, NFData)--instance Semigroup Directory where-    Directory components₀ <> Directory components₁ =-        Directory (components₁ <> components₀)--instance Pretty Directory where-    pretty (Directory {..}) = foldMap prettyPathComponent (reverse components)--prettyPathComponent :: Text -> Doc ann-prettyPathComponent text-    | Data.Text.all pathCharacter text =-        "/" <> Pretty.pretty text-    | otherwise =-        "/\"" <> Pretty.pretty text <> "\""--{-| A `File` is a `directory` followed by one additional path component-    representing the `file` name--}-data File = File-    { directory :: Directory-    , file      :: Text-    } deriving (Eq, Generic, Ord, Show, NFData)--instance Pretty File where-    pretty (File {..}) =-            Pretty.pretty directory-        <>  prettyPathComponent file--instance Semigroup File where-    File directory₀ _ <> File directory₁ file =-        File (directory₀ <> directory₁) file---- | The beginning of a file path which anchors subsequent path components-data FilePrefix-    = Absolute-    -- ^ Absolute path-    | Here-    -- ^ Path relative to @.@-    | Parent-    -- ^ Path relative to @..@-    | Home-    -- ^ Path relative to @~@-    deriving (Eq, Generic, Ord, Show, NFData)--instance Pretty FilePrefix where-    pretty Absolute = ""-    pretty Here     = "."-    pretty Parent   = ".."-    pretty Home     = "~"---- | The URI scheme-data Scheme = HTTP | HTTPS deriving (Eq, Generic, Ord, Show, NFData)---- | This type stores all of the components of a remote import-data URL = URL-    { scheme    :: Scheme-    , authority :: Text-    , path      :: File-    , query     :: Maybe Text-    , headers   :: Maybe (Expr Src Import)-    } deriving (Eq, Generic, Ord, Show, NFData)--instance Pretty URL where-    pretty (URL {..}) =-            schemeDoc-        <>  "://"-        <>  Pretty.pretty authority-        <>  pathDoc-        <>  queryDoc-        <>  foldMap prettyHeaders headers-      where-        prettyHeaders h =-          " using " <> Pretty.unAnnotate (prettyImportExpression h)--        File {..} = path--        Directory {..} = directory--        pathDoc =-                foldMap prettyURIComponent (reverse components)-            <>  prettyURIComponent file--        schemeDoc = case scheme of-            HTTP  -> "http"-            HTTPS -> "https"--        queryDoc = case query of-            Nothing -> ""-            Just q  -> "?" <> Pretty.pretty q--prettyURIComponent :: Text -> Doc ann-prettyURIComponent text =-        Pretty.pretty $ URI.normalizeCase $ URI.normalizeEscape $ "/" <> Data.Text.unpack text---- | The type of import (i.e. local vs. remote vs. environment)-data ImportType-    = Local FilePrefix File-    -- ^ Local path-    | Remote URL-    -- ^ URL of remote resource and optional headers stored in an import-    | Env  Text-    -- ^ Environment variable-    | Missing-    deriving (Eq, Generic, Ord, Show, NFData)--parent :: File-parent = File { directory = Directory { components = [ ".." ] }, file = "" }--instance Semigroup ImportType where-    Local prefix file₀ <> Local Here file₁ = Local prefix (file₀ <> file₁)--    Remote (URL { path = path₀, ..}) <> Local Here path₁ =-        Remote (URL { path = path₀ <> path₁, ..})--    Local prefix file₀ <> Local Parent file₁ =-        Local prefix (file₀ <> parent <> file₁)--    Remote (URL { path = path₀, .. }) <> Local Parent path₁ =-        Remote (URL { path = path₀ <> parent <> path₁, .. })--    import₀ <> Remote (URL { headers = headers₀, .. }) =-        Remote (URL { headers = headers₁, .. })-      where-        importHashed₀ = Import (ImportHashed Nothing import₀) Code--        headers₁ = fmap (fmap (importHashed₀ <>)) headers₀--    _ <> import₁ =-        import₁--instance Pretty ImportType where-    pretty (Local prefix file) =-        Pretty.pretty prefix <> Pretty.pretty file--    pretty (Remote url) = Pretty.pretty url--    pretty (Env env) = "env:" <> prettyEnvironmentVariable env--    pretty Missing = "missing"---- | How to interpret the import's contents (i.e. as Dhall code or raw text)-data ImportMode = Code | RawText | Location-  deriving (Eq, Generic, Ord, Show, NFData)---- | A `ImportType` extended with an optional hash for semantic integrity checks-data ImportHashed = ImportHashed-    { hash       :: Maybe Dhall.Crypto.SHA256Digest-    , importType :: ImportType-    } deriving (Eq, Generic, Ord, Show, NFData)--instance Semigroup ImportHashed where-    ImportHashed _ importType₀ <> ImportHashed hash importType₁ =-        ImportHashed hash (importType₀ <> importType₁)--instance Pretty ImportHashed where-    pretty (ImportHashed  Nothing p) =-      Pretty.pretty p-    pretty (ImportHashed (Just h) p) =-      Pretty.pretty p <> " sha256:" <> Pretty.pretty (show h)---- | Reference to an external resource-data Import = Import-    { importHashed :: ImportHashed-    , importMode   :: ImportMode-    } deriving (Eq, Generic, Ord, Show, NFData)--instance Semigroup Import where-    Import importHashed₀ _ <> Import importHashed₁ code =-        Import (importHashed₀ <> importHashed₁) code--instance Pretty Import where-    pretty (Import {..}) = Pretty.pretty importHashed <> Pretty.pretty suffix-      where-        suffix :: Text-        suffix = case importMode of-            RawText  -> " as Text"-            Location -> " as Location"-            Code     -> ""--{-| Returns `True` if the given `Char` is valid within an unquoted path-    component--    This is exported for reuse within the @"Dhall.Parser.Token"@ module--}-pathCharacter :: Char -> Bool-pathCharacter c =-         '\x21' == c-    ||  ('\x24' <= c && c <= '\x27')-    ||  ('\x2A' <= c && c <= '\x2B')-    ||  ('\x2D' <= c && c <= '\x2E')-    ||  ('\x30' <= c && c <= '\x3B')-    ||  c == '\x3D'-    ||  ('\x40' <= c && c <= '\x5A')-    ||  ('\x5E' <= c && c <= '\x7A')-    ||  c == '\x7C'-    ||  c == '\x7E'---- | Remove all `Note` constructors from an `Expr` (i.e. de-`Note`)-denote :: Expr s a -> Expr t a-denote = \case-    Note _ b      -> denote b-    Let a b       -> Let (denoteBinding a) (denote b)-    Embed a       -> Embed a-    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) 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-{-# INLINE renote #-}--{-| Remove any outermost `Note` constructors--    This is typically used when you want to get the outermost non-`Note`-    constructor without removing internal `Note` constructors--}-shallowDenote :: Expr s a -> Expr s a-shallowDenote (Note _ e) = shallowDenote e-shallowDenote         e  = e---- | The set of reserved keywords according to the @keyword@ rule in the grammar-reservedKeywords :: HashSet Text-reservedKeywords =-    Data.HashSet.fromList-        [-          "if"-        , "then"-        , "else"-        , "let"-        , "in"-        , "using"-        , "missing"-        , "as"-        , "Infinity"-        , "NaN"-        , "merge"-        , "Some"-        , "toMap"-        , "assert"-        , "forall"-        , "with"-        ]---- | The set of reserved identifiers for the Dhall language--- | Contains also all keywords from "reservedKeywords"-reservedIdentifiers :: HashSet Text-reservedIdentifiers = reservedKeywords <>-    Data.HashSet.fromList-        [ -- Builtins according to the `builtin` rule in the grammar-          "Natural/fold"-        , "Natural/build"-        , "Natural/isZero"-        , "Natural/even"-        , "Natural/odd"-        , "Natural/toInteger"-        , "Natural/show"-        , "Natural/subtract"-        , "Integer"-        , "Integer/clamp"-        , "Integer/negate"-        , "Integer/show"-        , "Integer/toDouble"-        , "Integer/show"-        , "Natural/subtract"-        , "Double/show"-        , "List/build"-        , "List/fold"-        , "List/length"-        , "List/head"-        , "List/last"-        , "List/indexed"-        , "List/reverse"-        , "Text/replace"-        , "Text/show"-        , "Bool"-        , "True"-        , "False"-        , "Optional"-        , "None"-        , "Natural"-        , "Integer"-        , "Double"-        , "Text"-        , "List"-        , "Type"-        , "Kind"-        , "Sort"-        ]---- | Same as @Data.Text.splitOn@, except always returning a `NonEmpty` result-splitOn :: Text -> Text -> NonEmpty Text-splitOn needle haystack =-    case Data.Text.splitOn needle haystack of-        []     -> "" :| []-        t : ts -> t  :| ts---- | Split `Chunks` by lines-linesLiteral :: Chunks s a -> NonEmpty (Chunks s a)-linesLiteral (Chunks [] suffix) =-    fmap (Chunks []) (splitOn "\n" suffix)-linesLiteral (Chunks ((prefix, interpolation) : pairs₀) suffix₀) =-    foldr-        NonEmpty.cons-        (Chunks ((lastLine, interpolation) : pairs₁) suffix₁ :| chunks)-        (fmap (Chunks []) initLines)-  where-    splitLines = splitOn "\n" prefix--    initLines = NonEmpty.init splitLines-    lastLine  = NonEmpty.last splitLines--    Chunks pairs₁ suffix₁ :| chunks = linesLiteral (Chunks pairs₀ suffix₀)---- | Flatten several `Chunks` back into a single `Chunks` by inserting newlines-unlinesLiteral :: NonEmpty (Chunks s a) -> Chunks s a-unlinesLiteral chunks =-    Data.Foldable.fold (NonEmpty.intersperse "\n" chunks)---- | Returns `True` if the `Chunks` represents a blank line-emptyLine :: Chunks s a -> Bool-emptyLine (Chunks [] ""  ) = True-emptyLine (Chunks [] "\r") = True  -- So that `\r\n` is treated as a blank line-emptyLine  _               = False---- | Return the leading whitespace for a `Chunks` literal-leadingSpaces :: Chunks s a -> Text-leadingSpaces chunks = Data.Text.takeWhile isSpace firstText-  where-    isSpace c = c == ' ' || c == '\t'--    firstText =-        case chunks of-            Chunks                []  suffix -> suffix-            Chunks ((prefix, _) : _ ) _      -> prefix--{-| Compute the longest shared whitespace prefix for the purposes of stripping-    leading indentation--}-longestSharedWhitespacePrefix :: NonEmpty (Chunks s a) -> Text-longestSharedWhitespacePrefix literals =-    case fmap leadingSpaces filteredLines of-        l : ls -> Data.Foldable.foldl' sharedPrefix l ls-        []     -> ""-  where-    sharedPrefix ab ac =-        case Data.Text.commonPrefixes ab ac of-            Just (a, _b, _c) -> a-            Nothing          -> ""--    -- The standard specifies to filter out blank lines for all lines *except*-    -- for the last line-    filteredLines = newInit <> pure oldLast-      where-        oldInit = NonEmpty.init literals--        oldLast = NonEmpty.last literals--        newInit = filter (not . emptyLine) oldInit---- | Drop the first @n@ characters for a `Chunks` literal-dropLiteral :: Int -> Chunks s a -> Chunks s a-dropLiteral n (Chunks [] suffix) =-    Chunks [] (Data.Text.drop n suffix)-dropLiteral n (Chunks ((prefix, interpolation) : rest) suffix) =-    Chunks ((Data.Text.drop n prefix, interpolation) : rest) suffix--{-| Convert a single-quoted `Chunks` literal to the equivalent double-quoted-    `Chunks` literal--}-toDoubleQuoted :: Chunks Src a -> Chunks Src a-toDoubleQuoted literal =-    unlinesLiteral (fmap (dropLiteral indent) literals)-  where-    literals = linesLiteral literal--    longestSharedPrefix = longestSharedWhitespacePrefix literals--    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) ])-            )-    rewrite e@(With record (key0 :| key1 : keys) value) =-        Just-            (Let-                (makeBinding "_" record)-                (Prefer (PreferFromWith e) "_"-                    (RecordLit-                        [ (key0, makeRecordField $ With (Field "_" (FieldSelection Nothing key0 Nothing)) (key1 :| keys) (shift 1 "_" value)) ]-                    )-                )-            )-    rewrite _ = Nothing--_ERROR :: String-_ERROR = "\ESC[1;31mError\ESC[0m"--{-| Utility function used to throw internal errors that should never happen-    (in theory) but that are not enforced by the type system--}-internalError :: Data.Text.Text -> forall b . b-internalError text = error (unlines-    [ _ERROR <> ": Compiler bug                                                        "-    , "                                                                                "-    , "Explanation: This error message means that there is a bug in the Dhall compiler."-    , "You didn't do anything wrong, but if you would like to see this problem fixed   "-    , "then you should report the bug at:                                              "-    , "                                                                                "-    , "https://github.com/dhall-lang/dhall-haskell/issues                              "-    , "                                                                                "-    , "Please include the following text in your bug report:                           "-    , "                                                                                "-    , "```                                                                             "-    , Data.Text.unpack text <> "                                                       "-    , "```                                                                             "-    ] )+module Dhall.Syntax+    ( module Export+    ) where++import {-# SOURCE #-} Dhall.Pretty.Internal              as Export+    ( CharacterSet (..)+    )+import                Dhall.Syntax.Binding               as Export+import                Dhall.Syntax.Chunks                as Export+import                Dhall.Syntax.Const                 as Export+import                Dhall.Syntax.Expr                  as Export+import                Dhall.Syntax.FunctionBinding       as Export+import                Dhall.Syntax.Import                as Export+import                Dhall.Syntax.Instances.Applicative as Export ()+import                Dhall.Syntax.Instances.Bifunctor   as Export ()+import                Dhall.Syntax.Instances.Data        as Export ()+import                Dhall.Syntax.Instances.Eq          as Export ()+import                Dhall.Syntax.Instances.Foldable    as Export ()+import                Dhall.Syntax.Instances.Functor     as Export ()+import                Dhall.Syntax.Instances.Lift        as Export ()+import                Dhall.Syntax.Instances.Monad       as Export ()+import                Dhall.Syntax.Instances.NFData      as Export ()+import                Dhall.Syntax.Instances.Ord         as Export ()+import                Dhall.Syntax.Instances.Pretty      as Export+import                Dhall.Syntax.Instances.Show        as Export ()+import                Dhall.Syntax.Instances.Traversable as Export ()+import                Dhall.Syntax.MultiLet              as Export+import                Dhall.Syntax.Operations            as Export+import                Dhall.Syntax.RecordField           as Export+import                Dhall.Syntax.Types                 as Export+import                Dhall.Syntax.Var                   as Export
− src/Dhall/Syntax.hs-boot
@@ -1,7 +0,0 @@-module Dhall.Syntax where--data Var--data Const--data Expr s a
+ src/Dhall/Syntax/Binding.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE DeriveGeneric #-}++module Dhall.Syntax.Binding+    ( Binding(..)+    , makeBinding++      -- * Optics+    , bindingExprs+    ) where++import                Data.Text         (Text)+import {-# SOURCE #-} Dhall.Syntax.Expr (Expr)+import                GHC.Generics      (Generic)++-- | Record the binding part of a @let@ expression.+--+-- For example,+--+-- > let {- A -} x {- B -} : {- C -} Bool = {- D -} True in x+--+-- … will be instantiated as follows:+--+-- * @bindingSrc0@ corresponds to the @A@ comment.+-- * @variable@ is @"x"@+-- * @bindingSrc1@ corresponds to the @B@ comment.+-- * @annotation@ is 'Just' a pair, corresponding to the @C@ comment and @Bool@.+-- * @bindingSrc2@ corresponds to the @D@ comment.+-- * @value@ corresponds to @True@.+data Binding s a = Binding+    { bindingSrc0 :: Maybe s+    , variable    :: Text+    , bindingSrc1 :: Maybe s+    , annotation  :: Maybe (Maybe s, Expr s a)+    , bindingSrc2 :: Maybe s+    , value       :: Expr s a+    } deriving Generic++{-| Construct a 'Binding' with no source information and no type annotation.+-}+makeBinding :: Text -> Expr s a -> Binding s a+makeBinding name = Binding Nothing name Nothing Nothing Nothing++{-| Traverse over the immediate 'Expr' children in a 'Binding'.+-}+bindingExprs+  :: (Applicative f)+  => (Expr s a -> f (Expr s b))+  -> Binding s a -> f (Binding s b)+bindingExprs f (Binding s0 n s1 t s2 v) =+  Binding+    <$> pure s0+    <*> pure n+    <*> pure s1+    <*> traverse (traverse f) t+    <*> pure s2+    <*> f v+{-# INLINABLE bindingExprs #-}
+ src/Dhall/Syntax/Chunks.hs view
@@ -0,0 +1,141 @@+{-# LANGUAGE DeriveGeneric     #-}+{-# LANGUAGE OverloadedStrings #-}++module Dhall.Syntax.Chunks+    ( Chunks(..)++      -- * Optics+    , chunkExprs++      -- * `Data.Text.Text` manipulation+    , toDoubleQuoted+    , longestSharedWhitespacePrefix+    , linesLiteral+    , unlinesLiteral+    ) where++import                Data.List.NonEmpty (NonEmpty (..))+import                Data.String        (IsString (..))+import                Data.Text          (Text)+import                Dhall.Src          (Src)+import {-# SOURCE #-} Dhall.Syntax.Expr  (Expr)+import                GHC.Generics       (Generic)++import qualified Data.Foldable+import qualified Data.List.NonEmpty as NonEmpty+import qualified Data.Text++-- | The body of an interpolated @Text@ literal+data Chunks s a = Chunks [(Text, Expr s a)] Text+    deriving Generic++instance IsString (Chunks s a) where+    fromString str = Chunks [] (fromString str)++instance Semigroup (Chunks s a) where+    Chunks xysL zL <> Chunks         []    zR =+        Chunks xysL (zL <> zR)+    Chunks xysL zL <> Chunks ((x, y):xysR) zR =+        Chunks (xysL ++ (zL <> x, y):xysR) zR++instance Monoid (Chunks s a) where+    mempty = Chunks [] mempty++-- | A traversal over the immediate sub-expressions in 'Chunks'.+chunkExprs+  :: Applicative f+  => (Expr s a -> f (Expr t b))+  -> Chunks s a -> f (Chunks t b)+chunkExprs f (Chunks chunks final) =+  flip Chunks final <$> traverse (traverse f) chunks+{-# INLINABLE chunkExprs #-}++-- | Same as @Data.Text.splitOn@, except always returning a `NonEmpty` result+splitOn :: Text -> Text -> NonEmpty Text+splitOn needle haystack =+    case Data.Text.splitOn needle haystack of+        []     -> "" :| []+        t : ts -> t  :| ts++-- | Split `Chunks` by lines+linesLiteral :: Chunks s a -> NonEmpty (Chunks s a)+linesLiteral (Chunks [] suffix) =+    fmap (Chunks []) (splitOn "\n" suffix)+linesLiteral (Chunks ((prefix, interpolation) : pairs₀) suffix₀) =+    foldr+        NonEmpty.cons+        (Chunks ((lastLine, interpolation) : pairs₁) suffix₁ :| chunks)+        (fmap (Chunks []) initLines)+  where+    splitLines = splitOn "\n" prefix++    initLines = NonEmpty.init splitLines+    lastLine  = NonEmpty.last splitLines++    Chunks pairs₁ suffix₁ :| chunks = linesLiteral (Chunks pairs₀ suffix₀)++-- | Flatten several `Chunks` back into a single `Chunks` by inserting newlines+unlinesLiteral :: NonEmpty (Chunks s a) -> Chunks s a+unlinesLiteral chunks =+    Data.Foldable.fold (NonEmpty.intersperse "\n" chunks)++-- | Returns `True` if the `Chunks` represents a blank line+emptyLine :: Chunks s a -> Bool+emptyLine (Chunks [] ""  ) = True+emptyLine (Chunks [] "\r") = True  -- So that `\r\n` is treated as a blank line+emptyLine  _               = False++-- | Return the leading whitespace for a `Chunks` literal+leadingSpaces :: Chunks s a -> Text+leadingSpaces chunks = Data.Text.takeWhile isSpace firstText+  where+    isSpace c = c == ' ' || c == '\t'++    firstText =+        case chunks of+            Chunks                []  suffix -> suffix+            Chunks ((prefix, _) : _ ) _      -> prefix++{-| Compute the longest shared whitespace prefix for the purposes of stripping+    leading indentation+-}+longestSharedWhitespacePrefix :: NonEmpty (Chunks s a) -> Text+longestSharedWhitespacePrefix literals =+    case fmap leadingSpaces filteredLines of+        l : ls -> Data.Foldable.foldl' sharedPrefix l ls+        []     -> ""+  where+    sharedPrefix ab ac =+        case Data.Text.commonPrefixes ab ac of+            Just (a, _b, _c) -> a+            Nothing          -> ""++    -- The standard specifies to filter out blank lines for all lines *except*+    -- for the last line+    filteredLines = newInit <> pure oldLast+      where+        oldInit = NonEmpty.init literals++        oldLast = NonEmpty.last literals++        newInit = filter (not . emptyLine) oldInit++-- | Drop the first @n@ characters for a `Chunks` literal+dropLiteral :: Int -> Chunks s a -> Chunks s a+dropLiteral n (Chunks [] suffix) =+    Chunks [] (Data.Text.drop n suffix)+dropLiteral n (Chunks ((prefix, interpolation) : rest) suffix) =+    Chunks ((Data.Text.drop n prefix, interpolation) : rest) suffix++{-| Convert a single-quoted `Chunks` literal to the equivalent double-quoted+    `Chunks` literal+-}+toDoubleQuoted :: Chunks Src a -> Chunks Src a+toDoubleQuoted literal =+    unlinesLiteral (fmap (dropLiteral indent) literals)+  where+    literals = linesLiteral literal++    longestSharedPrefix = longestSharedWhitespacePrefix literals++    indent = Data.Text.length longestSharedPrefix
+ src/Dhall/Syntax/Chunks.hs-boot view
@@ -0,0 +1,8 @@+{-# LANGUAGE StandaloneKindSignatures #-}++module Dhall.Syntax.Chunks where++import Data.Kind (Type)++type Chunks :: Type -> Type -> Type+data Chunks s a
+ src/Dhall/Syntax/Const.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE DeriveGeneric #-}++module Dhall.Syntax.Const+    ( Const(..)+    ) where++import GHC.Generics (Generic)++{-| Constants for a pure type system++    The axioms are:++> ⊦ Type : Kind+> ⊦ Kind : Sort++    ... and the valid rule pairs are:++> ⊦ Type ↝ Type : Type  -- Functions from terms to terms (ordinary functions)+> ⊦ Kind ↝ Type : Type  -- Functions from types to terms (type-polymorphic functions)+> ⊦ Sort ↝ Type : Type  -- Functions from kinds to terms+> ⊦ Kind ↝ Kind : Kind  -- Functions from types to types (type-level functions)+> ⊦ Sort ↝ Kind : Sort  -- Functions from kinds to types (kind-polymorphic functions)+> ⊦ Sort ↝ Sort : Sort  -- Functions from kinds to kinds (kind-level functions)++    Note that Dhall does not support functions from terms to types and therefore+    Dhall is not a dependently typed language+-}+data Const = Type | Kind | Sort+    deriving (Bounded, Enum, Generic)
+ src/Dhall/Syntax/Expr.hs view
@@ -0,0 +1,267 @@+{-# LANGUAGE DeriveGeneric            #-}+{-# LANGUAGE StandaloneKindSignatures #-}++module Dhall.Syntax.Expr+    ( Expr(..)+    ) where++import                Data.ByteString              (ByteString)+import                Data.Kind                    (Type)+import                Data.List.NonEmpty           (NonEmpty (..))+import                Data.Sequence                (Seq)+import                Data.String                  (IsString (..))+import                Data.Text                    (Text)+import                Data.Traversable             ()+import                Dhall.Map                    (Map)+import {-# SOURCE #-} Dhall.Pretty.Internal        (CharacterSet (..))+import                Dhall.Syntax.Binding+import                Dhall.Syntax.Chunks+import                Dhall.Syntax.Const+import                Dhall.Syntax.FunctionBinding+import                Dhall.Syntax.RecordField+import                Dhall.Syntax.Types+import                Dhall.Syntax.Var+import                GHC.Generics                 (Generic)+import                Numeric.Natural              (Natural)++import qualified Data.Time as Time++{-| Syntax tree for expressions++    The @s@ type parameter is used to track the presence or absence of+    `Dhall.Src.Src` spans:++    * If @s = `Dhall.Src.Src`@ then the code may contains `Dhall.Src.Src` spans+      (either in a `Note` constructor or inline within another constructor, like+      `Let`)+    * If @s = `Data.Void.Void`@ then the code has no `Dhall.Src.Src` spans++    The @a@ type parameter is used to track the presence or absence of imports++    * If @a = `Dhall.Syntax.Import.Import`@ then the code may contain unresolved+      `Dhall.Syntax.Import.Import`s+    * If @a = `Data.Void.Void`@ then the code has no+      `Dhall.Syntax.Import.Import`s+-}+type Expr :: Type -> Type -> Type+data Expr s a+    -- | > Const c                                  ~  c+    = Const Const+    -- | > Var (V x 0)                              ~  x+    --   > Var (V x n)                              ~  x@n+    | Var Var+    -- | > Lam _ (FunctionBinding _ "x" _ _ A) b    ~  λ(x : A) -> b+    | Lam (Maybe CharacterSet) (FunctionBinding s a) (Expr s a)+    -- | > Pi _ "_" A B                               ~        A  -> B+    --   > Pi _ x   A B                               ~  ∀(x : A) -> B+    | Pi  (Maybe CharacterSet) Text (Expr s a) (Expr s a)+    -- | > App f a                                  ~  f a+    | App (Expr s a) (Expr s a)+    -- | > Let (Binding _ x _  Nothing  _ r) e      ~  let x     = r in e+    --   > Let (Binding _ x _ (Just t ) _ r) e      ~  let x : t = r in e+    --+    -- The difference between+    --+    -- > let x = a    let y = b in e+    --+    -- and+    --+    -- > let x = a in let y = b in e+    --+    -- is only an additional 'Note' around @'Let' "y" …@ in the second+    -- example.+    --+    -- See `Dhall.Syntax.MultiLet.MultiLet` for a representation of let-blocks+    -- that mirrors the source code more closely.+    | Let (Binding s a) (Expr s a)+    -- | > Annot x t                                ~  x : t+    | Annot (Expr s a) (Expr s a)+    -- | > Bool                                     ~  Bool+    | Bool+    -- | > BoolLit b                                ~  b+    | BoolLit Bool+    -- | > BoolAnd x y                              ~  x && y+    | BoolAnd (Expr s a) (Expr s a)+    -- | > BoolOr  x y                              ~  x || y+    | BoolOr  (Expr s a) (Expr s a)+    -- | > BoolEQ  x y                              ~  x == y+    | BoolEQ  (Expr s a) (Expr s a)+    -- | > BoolNE  x y                              ~  x != y+    | BoolNE  (Expr s a) (Expr s a)+    -- | > BoolIf x y z                             ~  if x then y else z+    | BoolIf (Expr s a) (Expr s a) (Expr s a)+    -- | > Bytes                                    ~ Bytes+    | Bytes+    -- | > BytesLit "\x00\xFF"                      ~ 0x"00FF"+    | BytesLit ByteString+    -- | > Natural                                  ~  Natural+    | Natural+    -- | > NaturalLit n                             ~  n+    | NaturalLit Natural+    -- | > NaturalFold                              ~  Natural/fold+    | NaturalFold+    -- | > NaturalBuild                             ~  Natural/build+    | NaturalBuild+    -- | > NaturalIsZero                            ~  Natural/isZero+    | NaturalIsZero+    -- | > NaturalEven                              ~  Natural/even+    | NaturalEven+    -- | > NaturalOdd                               ~  Natural/odd+    | NaturalOdd+    -- | > NaturalToInteger                         ~  Natural/toInteger+    | NaturalToInteger+    -- | > NaturalShow                              ~  Natural/show+    | NaturalShow+    -- | > NaturalSubtract                          ~  Natural/subtract+    | NaturalSubtract+    -- | > NaturalPlus x y                          ~  x + y+    | NaturalPlus (Expr s a) (Expr s a)+    -- | > NaturalTimes x y                         ~  x * y+    | NaturalTimes (Expr s a) (Expr s a)+    -- | > Integer                                  ~  Integer+    | Integer+    -- | > IntegerLit n                             ~  ±n+    | IntegerLit Integer+    -- | > IntegerClamp                             ~  Integer/clamp+    | IntegerClamp+    -- | > IntegerNegate                            ~  Integer/negate+    | IntegerNegate+    -- | > IntegerShow                              ~  Integer/show+    | IntegerShow+    -- | > IntegerToDouble                          ~  Integer/toDouble+    | IntegerToDouble+    -- | > Double                                   ~  Double+    | Double+    -- | > DoubleLit n                              ~  n+    | DoubleLit DhallDouble+    -- | > DoubleShow                               ~  Double/show+    | DoubleShow+    -- | > Text                                     ~  Text+    | Text+    -- | > TextLit (Chunks [(t1, e1), (t2, e2)] t3) ~  "t1${e1}t2${e2}t3"+    | TextLit (Chunks s a)+    -- | > TextAppend x y                           ~  x ++ y+    | TextAppend (Expr s a) (Expr s a)+    -- | > TextReplace                              ~ Text/replace+    | TextReplace+    -- | > TextShow                                 ~  Text/show+    | TextShow+    -- | > Date                                     ~  Date+    | Date+    -- | > DateLiteral (fromGregorian _YYYY _MM _DD) ~ YYYY-MM-DD+    | DateLiteral Time.Day+    -- | > DateShow                                 ~  Date/show+    | DateShow+    -- | > Time                                     ~  Time+    | Time+    -- | > TimeLiteral (TimeOfDay hh mm ss) _       ~  hh:mm:ss+    | TimeLiteral+        Time.TimeOfDay+        Word+        -- ^ Precision+    -- | > TimeShow                                 ~  Time/show+    | TimeShow+    -- | > TimeZone                                 ~  TimeZone+    | TimeZone+    -- | > TimeZoneLiteral (TimeZone ( 60 * _HH + _MM) _ _) ~ +HH:MM+    -- | > TimeZoneLiteral (TimeZone (-60 * _HH + _MM) _ _) ~ -HH:MM+    | TimeZoneLiteral Time.TimeZone+    -- | > TimeZoneShow                             ~  TimeZone/Show+    | TimeZoneShow+    -- | > List                                     ~  List+    | List+    -- | > ListLit (Just t ) []                     ~  [] : t+    --   > ListLit  Nothing  [x, y, z]              ~  [x, y, z]+    --+    --   Invariant: A non-empty list literal is always represented as+    --   @ListLit Nothing xs@.+    --+    --   When an annotated, non-empty list literal is parsed, it is represented+    --   as+    --+    --   > Annot (ListLit Nothing [x, y, z]) t      ~ [x, y, z] : t++    -- Eventually we should have separate constructors for empty and non-empty+    -- list literals. For now it's easier to check the invariant in @infer@.+    -- See https://github.com/dhall-lang/dhall-haskell/issues/1359#issuecomment-537087234.+    | ListLit (Maybe (Expr s a)) (Seq (Expr s a))+    -- | > ListAppend x y                           ~  x # y+    | ListAppend (Expr s a) (Expr s a)+    -- | > ListBuild                                ~  List/build+    | ListBuild+    -- | > ListFold                                 ~  List/fold+    | ListFold+    -- | > ListLength                               ~  List/length+    | ListLength+    -- | > ListHead                                 ~  List/head+    | ListHead+    -- | > ListLast                                 ~  List/last+    | ListLast+    -- | > ListIndexed                              ~  List/indexed+    | ListIndexed+    -- | > ListReverse                              ~  List/reverse+    | ListReverse+    -- | > Optional                                 ~  Optional+    | Optional+    -- | > Some e                                   ~  Some e+    | Some (Expr s a)+    -- | > None                                     ~  None+    | None+    -- | > Record [ (k1, RecordField _ t1)          ~  { k1 : t1, k2 : t1 }+    --   >        , (k2, RecordField _ t2)+    --   >        ]+    | Record    (Map Text (RecordField s a))+    -- | > RecordLit [ (k1, RecordField _ v1)       ~  { k1 = v1, k2 = v2 }+    --   >           , (k2, RecordField _ v2)+    --   >           ]+    | RecordLit (Map Text (RecordField s a))+    -- | > Union        [(k1, Just t1), (k2, Nothing)] ~  < k1 : t1 | k2 >+    | Union     (Map Text (Maybe (Expr s a)))+    -- | > Combine _ Nothing x y                    ~  x ∧ y+    --+    -- The first field is a `Just` when the `Combine` operator is introduced+    -- as a result of desugaring duplicate record fields:+    --+    --   > RecordLit [ ( k                          ~ { k = x, k = y }+    --   >           , RecordField+    --   >              _+    --   >              (Combine (Just k) x y)+    --   >            )]+    | Combine (Maybe CharacterSet) (Maybe Text) (Expr s a) (Expr s a)+    -- | > CombineTypes _ x y                       ~  x ⩓ y+    | CombineTypes (Maybe CharacterSet) (Expr s a) (Expr s a)+    -- | > Prefer _ _ x y                           ~  x ⫽ y+    | Prefer (Maybe CharacterSet) PreferAnnotation (Expr s a) (Expr s a)+    -- | > RecordCompletion x y                     ~  x::y+    | RecordCompletion (Expr s a) (Expr s a)+    -- | > Merge x y (Just t )                      ~  merge x y : t+    --   > Merge x y  Nothing                       ~  merge x y+    | Merge (Expr s a) (Expr s a) (Maybe (Expr s a))+    -- | > ToMap x (Just t)                         ~  toMap x : t+    --   > ToMap x  Nothing                         ~  toMap x+    | ToMap (Expr s a) (Maybe (Expr s a))+    -- | > ShowConstructor x                        ~  showConstructor x+    | ShowConstructor (Expr s a)+    -- | > 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 [Text] (Expr s a))+    -- | > Assert e                                 ~  assert : e+    | Assert (Expr s a)+    -- | > Equivalent _ x y                           ~  x ≡ y+    | Equivalent (Maybe CharacterSet) (Expr s a) (Expr s a)+    -- | > With x y e                               ~  x with y = e+    | With (Expr s a) (NonEmpty WithComponent) (Expr s a)+    -- | > Note s x                                 ~  e+    | Note s (Expr s a)+    -- | > ImportAlt                                ~  e1 ? e2+    | ImportAlt (Expr s a) (Expr s a)+    -- | > Embed import                             ~  import+    | Embed a+    deriving (Generic)+-- NB: If you add a constructor to Expr, please also update the Arbitrary+-- instance in Dhall.Test.QuickCheck.++instance IsString (Expr s a) where+    fromString str = Var (fromString str)
+ src/Dhall/Syntax/Expr.hs-boot view
@@ -0,0 +1,8 @@+{-# LANGUAGE StandaloneKindSignatures #-}++module Dhall.Syntax.Expr where++import Data.Kind (Type)++type Expr :: Type -> Type -> Type+data Expr s a
+ src/Dhall/Syntax/FunctionBinding.hs view
@@ -0,0 +1,53 @@+{-# LANGUAGE DeriveGeneric #-}++module Dhall.Syntax.FunctionBinding+    ( FunctionBinding(..)+    , makeFunctionBinding++      -- * Optics+    , functionBindingExprs+    ) where++import                Data.Text         (Text)+import {-# SOURCE #-} Dhall.Syntax.Expr (Expr)+import                GHC.Generics      (Generic)++-- | 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 Generic++-- | 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++{-| 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_+{-# INLINABLE functionBindingExprs #-}
+ src/Dhall/Syntax/Import.hs view
@@ -0,0 +1,139 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveGeneric      #-}+{-# LANGUAGE OverloadedStrings  #-}+{-# LANGUAGE RecordWildCards    #-}++module Dhall.Syntax.Import+    ( Directory(..)+    , File(..)+    , FilePrefix(..)+    , Import(..)+    , ImportHashed(..)+    , ImportMode(..)+    , ImportType(..)+    , URL(..)+    , Scheme(..)+    ) where++import Data.Data                      (Data)+import Data.Text                      (Text)+import Dhall.Src                      (Src (..))+import Dhall.Syntax.Expr              (Expr (..))+import Dhall.Syntax.Instances.Data    ()+import Dhall.Syntax.Instances.Functor ()+import GHC.Generics                   (Generic)++import qualified Dhall.Crypto++{-| Internal representation of a directory that stores the path components in+    reverse order++    In other words, the directory @\/foo\/bar\/baz@ is encoded as+    @Directory { components = [ "baz", "bar", "foo" ] }@+-}+newtype Directory = Directory { components :: [Text] }+    deriving (Data, Generic)++{-| A `File` is a `directory` followed by one additional path component+    representing the `file` name+-}+data File = File+    { directory :: Directory+    , file      :: Text+    } deriving (Data, Generic)++-- | The beginning of a file path which anchors subsequent path components+data FilePrefix+    = Absolute+    -- ^ Absolute path+    | Here+    -- ^ Path relative to @.@+    | Parent+    -- ^ Path relative to @..@+    | Home+    -- ^ Path relative to @~@+    deriving (Data, Generic)++-- | The URI scheme+data Scheme = HTTP | HTTPS+    deriving (Data, Generic)++-- | This type stores all of the components of a remote import+data URL = URL+    { scheme    :: Scheme+    , authority :: Text+    , path      :: File+    , query     :: Maybe Text+    , headers   :: Maybe (Expr Src Import)+    } deriving (Data, Generic)++-- | The type of import (i.e. local vs. remote vs. environment)+data ImportType+    = Local FilePrefix File+    -- ^ Local path+    | Remote URL+    -- ^ URL of remote resource and optional headers stored in an import+    | Env  Text+    -- ^ Environment variable+    | Missing+    deriving (Data, Generic)++-- | How to interpret the import's contents (i.e. as Dhall code or raw text)+data ImportMode = Code | RawText | Location | RawBytes+  deriving (Data, Generic)++-- | A `ImportType` extended with an optional hash for semantic integrity checks+data ImportHashed = ImportHashed+    { hash       :: Maybe Dhall.Crypto.SHA256Digest+    , importType :: ImportType+    } deriving (Data, Generic)++-- | Reference to an external resource+data Import = Import+    { importHashed :: ImportHashed+    , importMode   :: ImportMode+    } deriving (Data, Generic)+++++instance Semigroup Directory where+    Directory components0 <> Directory components1 =+        Directory (components1 <> components0)++instance Semigroup File where+    File directory0 _ <> File directory1 file =+        File (directory0 <> directory1) file++instance Semigroup ImportType where+    Local prefix file0 <> Local Here file1 = Local prefix (file0 <> file1)++    Remote (URL { path = path0, ..}) <> Local Here path1 =+        Remote (URL { path = path0 <> path1, ..})++    Local prefix file0 <> Local Parent file1 =+        Local prefix (file0 <> parent <> file1)++    Remote (URL { path = path0, .. }) <> Local Parent path1 =+        Remote (URL { path = path0 <> parent <> path1, .. })++    import0 <> Remote (URL { headers = headers0, .. }) =+        Remote (URL { headers = headers1, .. })+      where+        importHashed0 = Import (ImportHashed Nothing import0) Code++        headers1 = fmap (fmap (importHashed0 <>)) headers0++    _ <> import1 =+        import1++instance Semigroup ImportHashed where+    ImportHashed _ importType0 <> ImportHashed hash importType1 =+        ImportHashed hash (importType0 <> importType1)++instance Semigroup Import where+    Import importHashed0 _ <> Import importHashed1 code =+        Import (importHashed0 <> importHashed1) code++parent :: File+parent = File { directory = Directory { components = [ ".." ] }, file = "" }
+ src/Dhall/Syntax/Instances/Applicative.hs view
@@ -0,0 +1,36 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module Dhall.Syntax.Instances.Applicative () where++import Dhall.Syntax.Binding+import Dhall.Syntax.Expr+import Dhall.Syntax.FunctionBinding+import Dhall.Syntax.Instances.Functor ()+import Dhall.Syntax.Operations+import Dhall.Syntax.RecordField++import qualified Lens.Micro as Lens++instance Applicative (Expr s) where+    pure = Embed++    expression <*> k = case expression of+        Embed a     -> a <$> k+        Let a b     -> Let (adaptBinding a) (b <*> k)+        Note a b    -> Note a (b <*> k)+        Record a    -> Record $ adaptRecordField <$> a+        RecordLit a -> RecordLit $ adaptRecordField <$> a+        Lam cs a b  -> Lam cs (adaptFunctionBinding a) (b <*> k)+        Field a b   -> Field (a <*> k) b+        _ -> Lens.over unsafeSubExpressions (<*> k) expression+      where+        adaptRecordField (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)
+ src/Dhall/Syntax/Instances/Bifunctor.hs view
@@ -0,0 +1,44 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module Dhall.Syntax.Instances.Bifunctor () where++import Data.Bifunctor                 (Bifunctor (..))+import Dhall.Syntax.Binding+import Dhall.Syntax.Expr+import Dhall.Syntax.FunctionBinding+import Dhall.Syntax.Instances.Functor ()+import Dhall.Syntax.Operations+import Dhall.Syntax.RecordField++import qualified Lens.Micro as Lens++instance Bifunctor Binding where+    first k (Binding src0 a src1 b src2 c) =+        Binding (fmap k src0) a (fmap k src1) (fmap adapt0 b) (fmap k src2) (first k c)+      where+        adapt0 (src3, d) = (fmap k src3, first k d)++    second = fmap++instance Bifunctor RecordField where+    first k (RecordField s0 value' s1 s2) =+        RecordField (k <$> s0) (first k value') (k <$> s1) (k <$> s2)+    second = fmap++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++instance Bifunctor Expr where+    first k (Note a b   ) = Note (k a) (first k b)+    first _ (Embed a    ) = Embed a+    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 cs a b ) = Lam cs (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
+ src/Dhall/Syntax/Instances/Data.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE StandaloneDeriving #-}++{-# OPTIONS_GHC -Wno-orphans #-}++module Dhall.Syntax.Instances.Data () where++import Data.Data                    (Data)+import Dhall.Syntax.Binding+import Dhall.Syntax.Chunks+import Dhall.Syntax.Const+import Dhall.Syntax.Expr+import Dhall.Syntax.FunctionBinding+import Dhall.Syntax.RecordField+import Dhall.Syntax.Types+import Dhall.Syntax.Var++deriving instance Data Const+deriving instance Data Var+deriving instance (Data a, Data s) => Data (Binding s a)+deriving instance Data DhallDouble+deriving instance (Data a, Data s) => Data (Chunks s a)+deriving instance Data PreferAnnotation+deriving instance (Data a, Data s) => Data (RecordField s a)+deriving instance (Data a, Data s) => Data (FunctionBinding s a)+deriving instance Data s => Data (FieldSelection s)+deriving instance Data WithComponent+deriving instance (Data a, Data s) => Data (Expr s a)
+ src/Dhall/Syntax/Instances/Eq.hs view
@@ -0,0 +1,67 @@+{-# LANGUAGE StandaloneDeriving #-}++{-# OPTIONS_GHC -Wno-orphans #-}++module Dhall.Syntax.Instances.Eq () where++import Data.Bits                    (xor)+import Dhall.Syntax.Binding+import Dhall.Syntax.Chunks+import Dhall.Syntax.Const+import Dhall.Syntax.Expr+import Dhall.Syntax.FunctionBinding+import Dhall.Syntax.Import+import Dhall.Syntax.RecordField+import Dhall.Syntax.Types+import Dhall.Syntax.Var++-- $setup+-- >>> import Data.Void (Void)+-- >>> import Dhall.Binary () -- For the orphan instance for `Serialise (Expr Void Import)`++deriving instance Eq Const+deriving instance Eq Var+deriving instance (Eq s, Eq a) => Eq (Binding s a)+deriving instance (Eq s, Eq a) => Eq (Chunks s a)+deriving instance Eq PreferAnnotation+deriving instance (Eq s, Eq a) => Eq (RecordField s a)+deriving instance (Eq s, Eq a) => Eq (FunctionBinding s a)+deriving instance Eq s => Eq (FieldSelection s)+deriving instance Eq WithComponent+-- | This instance encodes what the Dhall standard calls an \"exact match\"+-- between two expressions.+--+-- Note that+--+-- >>> nan = DhallDouble (0/0)+-- >>> DoubleLit nan == DoubleLit nan+-- True+deriving instance (Eq s, Eq a) => Eq (Expr s a)+deriving instance Eq Directory+deriving instance Eq File+deriving instance Eq FilePrefix+deriving instance Eq Scheme+deriving instance Eq URL+deriving instance Eq ImportType+deriving instance Eq ImportMode+deriving instance Eq ImportHashed+deriving instance Eq Import++-- | This instance satisfies all the customary 'Eq' laws except substitutivity.+--+-- In particular:+--+-- >>> nan = DhallDouble (0/0)+-- >>> nan == nan+-- True+--+-- This instance is also consistent with with the binary encoding of Dhall @Double@s:+--+-- >>> toBytes n = Dhall.Binary.encodeExpression (DoubleLit n :: Expr Void Import)+--+-- prop> \a b -> (a == b) == (toBytes a == toBytes b)+instance Eq DhallDouble where+    DhallDouble a == DhallDouble b+        | isNaN a && isNaN b                      = True+        | isNegativeZero a `xor` isNegativeZero b = False+        | otherwise                               = a == b
+ src/Dhall/Syntax/Instances/Foldable.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE DeriveFoldable     #-}+{-# LANGUAGE StandaloneDeriving #-}++{-# OPTIONS_GHC -Wno-orphans #-}++module Dhall.Syntax.Instances.Foldable () where++import Dhall.Syntax.Binding+import Dhall.Syntax.Chunks+import Dhall.Syntax.Expr+import Dhall.Syntax.FunctionBinding+import Dhall.Syntax.RecordField+import Dhall.Syntax.Types++deriving instance Foldable (Binding s)+deriving instance Foldable (Chunks s)+deriving instance Foldable (RecordField s)+deriving instance Foldable (FunctionBinding s)+deriving instance Foldable FieldSelection+deriving instance Foldable (Expr s)
+ src/Dhall/Syntax/Instances/Functor.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE DeriveFunctor      #-}+{-# LANGUAGE StandaloneDeriving #-}++{-# OPTIONS_GHC -Wno-orphans #-}++module Dhall.Syntax.Instances.Functor () where++import                Dhall.Syntax.Binding+import                Dhall.Syntax.Chunks+import                Dhall.Syntax.Expr+import                Dhall.Syntax.FunctionBinding+import {-# SOURCE #-} Dhall.Syntax.Operations      (unsafeSubExpressions)+import                Dhall.Syntax.RecordField+import                Dhall.Syntax.Types++import qualified Lens.Micro as Lens++deriving instance Functor (Binding s)+deriving instance Functor (Chunks s)+deriving instance Functor (RecordField s)+deriving instance Functor (FunctionBinding s)+deriving instance Functor FieldSelection++-- This instance is hand-written due to the fact that deriving+-- it does not give us an INLINABLE pragma. We annotate this fmap+-- implementation with this pragma below to allow GHC to, possibly,+-- inline the implementation for performance improvements.+instance Functor (Expr s) where+  fmap f (Embed a) = Embed (f a)+  fmap f (Let b e2) = Let (fmap f b) (fmap f e2)+  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 cs fb e) = Lam cs (f <$> fb) (f <$> e)+  fmap f (Field a b) = Field (f <$> a) b+  fmap f expression = Lens.over unsafeSubExpressions (fmap f) expression+  {-# INLINABLE fmap #-}
+ src/Dhall/Syntax/Instances/Lift.hs view
@@ -0,0 +1,42 @@+{-# LANGUAGE CPP                #-}+{-# LANGUAGE DeriveLift         #-}+{-# LANGUAGE StandaloneDeriving #-}++{-# OPTIONS_GHC -Wno-orphans #-}++module Dhall.Syntax.Instances.Lift () where++import Dhall.Syntax.Binding+import Dhall.Syntax.Chunks+import Dhall.Syntax.Const+import Dhall.Syntax.Expr+import Dhall.Syntax.FunctionBinding+import Dhall.Syntax.RecordField+import Dhall.Syntax.Types+import Dhall.Syntax.Var+import Language.Haskell.TH.Syntax   (Lift)++#if !MIN_VERSION_template_haskell(2,21,0)+import qualified Data.Fixed as Fixed+#endif+import qualified Data.Time as Time++#if !MIN_VERSION_time(1,14,0)+deriving instance Lift Time.Day+#endif+deriving instance Lift Time.TimeOfDay+deriving instance Lift Time.TimeZone+#if !MIN_VERSION_template_haskell(2,21,0)+deriving instance Lift (Fixed.Fixed a)+#endif+deriving instance Lift Const+deriving instance Lift Var+deriving instance (Lift s, Lift a) => Lift (Binding s a)+deriving instance Lift DhallDouble+deriving instance (Lift s, Lift a) => Lift (Chunks s a)+deriving instance Lift PreferAnnotation+deriving instance (Lift s, Lift a) => Lift (RecordField s a)+deriving instance (Lift s, Lift a) => Lift (FunctionBinding s a)+deriving instance Lift s => Lift (FieldSelection s)+deriving instance Lift WithComponent+deriving instance (Lift s, Lift a) => Lift (Expr s a)
+ src/Dhall/Syntax/Instances/Monad.hs view
@@ -0,0 +1,36 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module Dhall.Syntax.Instances.Monad () where++import Dhall.Syntax.Binding+import Dhall.Syntax.Expr+import Dhall.Syntax.FunctionBinding+import Dhall.Syntax.Instances.Applicative ()+import Dhall.Syntax.Operations+import Dhall.Syntax.RecordField++import qualified Lens.Micro as Lens++instance Monad (Expr s) where+    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+        RecordLit a -> RecordLit $ bindRecordKeyValues <$> a+        Lam cs a b  -> Lam cs (adaptFunctionBinding a) (b >>= k)+        Field a b   -> Field (a >>= k) b+        _ -> Lens.over unsafeSubExpressions (>>= k) expression+      where+        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)
+ src/Dhall/Syntax/Instances/NFData.hs view
@@ -0,0 +1,35 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module Dhall.Syntax.Instances.NFData () where++import Control.DeepSeq              (NFData)+import Dhall.Syntax.Binding+import Dhall.Syntax.Chunks+import Dhall.Syntax.Const+import Dhall.Syntax.Expr+import Dhall.Syntax.FunctionBinding+import Dhall.Syntax.Import+import Dhall.Syntax.RecordField+import Dhall.Syntax.Types+import Dhall.Syntax.Var++instance NFData Const+instance NFData Var+instance (NFData s, NFData a) => NFData (Binding s a)+instance NFData DhallDouble+instance (NFData s, NFData a) => NFData (Chunks s a)+instance NFData PreferAnnotation+instance (NFData s, NFData a) => NFData (RecordField s a)+instance (NFData s, NFData a) => NFData (FunctionBinding s a)+instance NFData s => NFData (FieldSelection s)+instance NFData WithComponent+instance (NFData s, NFData a) => NFData (Expr s a)+instance NFData Directory+instance NFData File+instance NFData FilePrefix+instance NFData Scheme+instance NFData URL+instance NFData ImportType+instance NFData ImportMode+instance NFData ImportHashed+instance NFData Import
+ src/Dhall/Syntax/Instances/Ord.hs view
@@ -0,0 +1,45 @@+{-# LANGUAGE StandaloneDeriving #-}++{-# OPTIONS_GHC -Wno-orphans #-}++module Dhall.Syntax.Instances.Ord () where++import Dhall.Syntax.Binding+import Dhall.Syntax.Chunks+import Dhall.Syntax.Const+import Dhall.Syntax.Expr+import Dhall.Syntax.FunctionBinding+import Dhall.Syntax.Import+import Dhall.Syntax.Instances.Eq    ()+import Dhall.Syntax.RecordField+import Dhall.Syntax.Types+import Dhall.Syntax.Var++deriving instance Ord Const+deriving instance Ord Var+deriving instance (Ord s, Ord a) => Ord (Binding s a)+deriving instance (Ord s, Ord a) => Ord (Chunks s a)+deriving instance Ord PreferAnnotation+deriving instance (Ord s, Ord a) => Ord (RecordField s a)+deriving instance (Ord s, Ord a) => Ord (FunctionBinding s a)+deriving instance Ord s => Ord (FieldSelection s)+deriving instance Ord WithComponent+-- | Note that this 'Ord' instance inherits `DhallDouble`'s defects.+deriving instance (Ord s, Ord a) => Ord (Expr s a)+deriving instance Ord Directory+deriving instance Ord File+deriving instance Ord FilePrefix+deriving instance Ord Scheme+deriving instance Ord URL+deriving instance Ord ImportType+deriving instance Ord ImportMode+deriving instance Ord ImportHashed+deriving instance Ord Import++-- | This instance relies on the 'Eq' instance for 'DhallDouble' but cannot+-- satisfy the customary 'Ord' laws when @NaN@ is involved.+instance Ord DhallDouble where+    compare a@(DhallDouble a') b@(DhallDouble b') =+        if a == b+            then EQ+            else compare a' b'
+ src/Dhall/Syntax/Instances/Pretty.hs view
@@ -0,0 +1,135 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards   #-}++{-# OPTIONS_GHC -Wno-orphans #-}++module Dhall.Syntax.Instances.Pretty+    ( pathCharacter+    ) where++import                Data.Text             (Text)+import {-# SOURCE #-} Dhall.Pretty.Internal+import                Dhall.Syntax.Const+import                Dhall.Syntax.Expr+import                Dhall.Syntax.Import+import                Dhall.Syntax.Var+import                Prettyprinter         (Doc, Pretty)++import qualified Data.Text+import qualified Network.URI   as URI+import qualified Prettyprinter as Pretty++instance Pretty Const where+    pretty = Pretty.unAnnotate . prettyConst++instance Pretty Var where+    pretty = Pretty.unAnnotate . prettyVar++-- | Generates a syntactically valid Dhall program+instance Pretty a => Pretty (Expr s a) where+    pretty = Pretty.unAnnotate . prettyExpr++instance Pretty Directory where+    pretty (Directory {..}) = foldMap prettyPathComponent (reverse components)++prettyPathComponent :: Text -> Doc ann+prettyPathComponent text+    | Data.Text.all pathCharacter text =+        "/" <> Pretty.pretty text+    | otherwise =+        "/\"" <> Pretty.pretty text <> "\""++instance Pretty File where+    pretty (File {..}) =+            Pretty.pretty directory+        <>  prettyPathComponent file++instance Pretty FilePrefix where+    pretty Absolute = ""+    pretty Here     = "."+    pretty Parent   = ".."+    pretty Home     = "~"++instance Pretty URL where+    pretty (URL {..}) =+            schemeDoc+        <>  "://"+        <>  Pretty.pretty authority+        <>  pathDoc+        <>  queryDoc+        <>  foldMap prettyHeaders headers+      where+        prettyHeaders h =+          " using (" <> Pretty.unAnnotate (Pretty.pretty h) <> ")"++        File {..} = path++        Directory {..} = directory++        pathDoc =+                foldMap prettyURIComponent (reverse components)+            <>  prettyURIComponent file++        schemeDoc = case scheme of+            HTTP  -> "http"+            HTTPS -> "https"++        queryDoc = case query of+            Nothing -> ""+            Just q  -> "?" <> Pretty.pretty q++prettyURIComponent :: Text -> Doc ann+prettyURIComponent text =+        Pretty.pretty $ URI.normalizeCase $ URI.normalizeEscape $ "/" <> Data.Text.unpack text++instance Pretty ImportType where+    pretty (Local prefix file) =+        Pretty.pretty prefix <> Pretty.pretty file++    pretty (Remote url) = Pretty.pretty url++    pretty (Env env) = "env:" <> prettyEnvironmentVariable env++    pretty Missing = "missing"++instance Pretty ImportHashed where+    pretty (ImportHashed  Nothing p) =+      Pretty.pretty p+    pretty (ImportHashed (Just h) p) =+      Pretty.group (Pretty.flatAlt long short)+      where+        long =+            Pretty.align+                (   Pretty.pretty p <> Pretty.hardline+                <>  "  sha256:" <> Pretty.pretty (show h)+                )++        short = Pretty.pretty p <> " sha256:" <> Pretty.pretty (show h)++instance Pretty Import where+    pretty (Import {..}) = Pretty.pretty importHashed <> Pretty.pretty suffix+      where+        suffix :: Text+        suffix = case importMode of+            RawText  -> " as Text"+            Location -> " as Location"+            Code     -> ""+            RawBytes -> " as Bytes"++{-| Returns `True` if the given `Char` is valid within an unquoted path+    component++    This is exported for reuse within the @"Dhall.Parser.Token"@ module+-}+pathCharacter :: Char -> Bool+pathCharacter c =+         '\x21' == c+    ||  ('\x24' <= c && c <= '\x27')+    ||  ('\x2A' <= c && c <= '\x2B')+    ||  ('\x2D' <= c && c <= '\x2E')+    ||  ('\x30' <= c && c <= '\x3B')+    ||  c == '\x3D'+    ||  ('\x40' <= c && c <= '\x5A')+    ||  ('\x5E' <= c && c <= '\x7A')+    ||  c == '\x7C'+    ||  c == '\x7E'
+ src/Dhall/Syntax/Instances/Pretty.hs-boot view
@@ -0,0 +1,8 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module Dhall.Syntax.Instances.Pretty where++import Dhall.Syntax.Expr (Expr)+import Prettyprinter     (Pretty)++instance Pretty a => Pretty (Expr s a)
+ src/Dhall/Syntax/Instances/Show.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE StandaloneDeriving #-}++{-# OPTIONS_GHC -Wno-orphans #-}++module Dhall.Syntax.Instances.Show () where++import Dhall.Syntax.Binding+import Dhall.Syntax.Chunks+import Dhall.Syntax.Const+import Dhall.Syntax.Expr+import Dhall.Syntax.FunctionBinding+import Dhall.Syntax.Import+import Dhall.Syntax.RecordField+import Dhall.Syntax.Types+import Dhall.Syntax.Var++deriving instance Show Const+deriving instance Show Var+deriving instance (Show s, Show a) => Show (Binding s a)+deriving instance Show DhallDouble+deriving instance (Show s, Show a) => Show (Chunks s a)+deriving instance Show PreferAnnotation+deriving instance (Show s, Show a) => Show (RecordField s a)+deriving instance (Show s, Show a) => Show (FunctionBinding s a)+deriving instance Show s => Show (FieldSelection s)+deriving instance Show WithComponent+deriving instance (Show s, Show a) => Show (Expr s a)+deriving instance Show Directory+deriving instance Show File+deriving instance Show FilePrefix+deriving instance Show Scheme+deriving instance Show URL+deriving instance Show ImportType+deriving instance Show ImportMode+deriving instance Show ImportHashed+deriving instance Show Import
+ src/Dhall/Syntax/Instances/Traversable.hs view
@@ -0,0 +1,22 @@+{-# LANGUAGE DeriveTraversable  #-}+{-# LANGUAGE StandaloneDeriving #-}++{-# OPTIONS_GHC -Wno-orphans #-}++module Dhall.Syntax.Instances.Traversable () where++import Dhall.Syntax.Binding+import Dhall.Syntax.Chunks+import Dhall.Syntax.Expr+import Dhall.Syntax.FunctionBinding+import Dhall.Syntax.Instances.Foldable ()+import Dhall.Syntax.Instances.Functor  ()+import Dhall.Syntax.RecordField+import Dhall.Syntax.Types++deriving instance Traversable (Binding s)+deriving instance Traversable (Chunks s)+deriving instance Traversable (RecordField s)+deriving instance Traversable (FunctionBinding s)+deriving instance Traversable FieldSelection+deriving instance Traversable (Expr s)
+ src/Dhall/Syntax/MultiLet.hs view
@@ -0,0 +1,62 @@+{-# LANGUAGE LambdaCase #-}++{- | Instead of converting explicitly between 'Expr's and 'MultiLet', it might+be nicer to use a pattern synonym:++> pattern MultiLet' :: NonEmpty (Binding s a) -> Expr s a -> Expr s a+> pattern MultiLet' as b <- (multiLetFromExpr -> Just (MultiLet as b)) where+>   MultiLet' as b = wrapInLets as b+>+> multiLetFromExpr :: Expr s a -> Maybe (MultiLet s a)+> multiLetFromExpr = \case+>     Let x mA a b -> Just (multiLet x mA a b)+>     _ -> Nothing++This works in principle, but GHC as of v8.8.1 doesn't handle it well:+https://gitlab.haskell.org/ghc/ghc/issues/17096++This should be fixed by GHC-8.10, so it might be worth revisiting then.+-}++module Dhall.Syntax.MultiLet+    ( MultiLet(..)+    , multiLet+    , wrapInLets+    ) where++import Data.List.NonEmpty   (NonEmpty (..))+import Dhall.Syntax.Binding (Binding)+import Dhall.Syntax.Expr    (Expr (..))++import qualified Data.List.NonEmpty as NonEmpty++{-| Generate a 'MultiLet' from the contents of a 'Let'.++    In the resulting @'MultiLet' bs e@, @e@ is guaranteed not to be a 'Let',+    but it might be a @('Note' … ('Let' …))@.++    Given parser output, 'multiLet' consolidates @let@s that formed a+    let-block in the original source.+-}+multiLet :: Binding s a -> Expr s a -> MultiLet s a+multiLet b0 = \case+    Let b1 e1 ->+        let MultiLet bs e = multiLet b1 e1+        in  MultiLet (NonEmpty.cons b0 bs) e+    e -> MultiLet (b0 :| []) e++{-| Wrap let-'Binding's around an 'Expr'.++'wrapInLets' can be understood as an inverse for 'multiLet':++> let MultiLet bs e1 = multiLet b e0+>+> wrapInLets bs e1 == Let b e0+-}+wrapInLets :: Foldable f => f (Binding s a) -> Expr s a -> Expr s a+wrapInLets bs e = foldr Let e bs++{-| This type represents 1 or more nested `Let` bindings that have been+    coalesced together for ease of manipulation+-}+data MultiLet s a = MultiLet (NonEmpty (Binding s a)) (Expr s a)
+ src/Dhall/Syntax/Operations.hs view
@@ -0,0 +1,394 @@+{-# LANGUAGE LambdaCase        #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes        #-}++module Dhall.Syntax.Operations+    ( -- * Optics+      subExpressions+    , subExpressionsWith+    , unsafeSubExpressions++      -- * Handling 'Note's+    , denote+    , renote+    , shallowDenote++      -- * Reserved identifiers+    , reservedIdentifiers+    , reservedKeywords++      -- * Utilities+    , internalError+      -- `shift` should really be in `Dhall.Normalize`, but it's here to avoid a+      -- module cycle+    , shift+    ) where++import Data.HashSet                 (HashSet)+import Data.Text                    (Text)+import Data.Void                    (Void)+import Dhall.Syntax.Binding         (Binding (..), bindingExprs)+import Dhall.Syntax.Chunks          (chunkExprs)+import Dhall.Syntax.Expr+import Dhall.Syntax.FunctionBinding+import Dhall.Syntax.RecordField     (RecordField (..), recordFieldExprs)+import Dhall.Syntax.Types+import Dhall.Syntax.Var+import Unsafe.Coerce                (unsafeCoerce)++import qualified Data.HashSet+import qualified Data.Text+import qualified Lens.Micro   as Lens+++-- | A traversal over the immediate sub-expressions of an expression.+subExpressions+    :: Applicative f => (Expr s a -> f (Expr s a)) -> Expr s a -> f (Expr s a)+subExpressions = subExpressionsWith (pure . Embed)+{-# INLINABLE subExpressions #-}++{-| A traversal over the immediate sub-expressions of an expression which+    allows mapping embedded values+-}+subExpressionsWith+    :: Applicative f => (a -> f (Expr s b)) -> (Expr s a -> f (Expr s b)) -> Expr s a -> f (Expr s b)+subExpressionsWith h _ (Embed a) = h a+subExpressionsWith _ f (Note a b) = Note a <$> f b+subExpressionsWith _ f (Let a b) = Let <$> bindingExprs f a <*> f b+subExpressionsWith _ f (Record a) = Record <$> traverse (recordFieldExprs f) a+subExpressionsWith _ f (RecordLit a) = RecordLit <$> traverse (recordFieldExprs f) a+subExpressionsWith _ f (Lam cs fb e) = Lam cs <$> functionBindingExprs f fb <*> f e+subExpressionsWith _ f (Field a b) = Field <$> f a <*> pure b+subExpressionsWith _ f expression = unsafeSubExpressions f expression+{-# INLINABLE subExpressionsWith #-}++{-| An internal utility used to implement transformations that require changing+    one of the type variables of the `Expr` type++    This utility only works because the implementation is partial, not+    handling the `Let`, `Note`, or `Embed` cases, which need to be handled by+    the caller.+-}+unsafeSubExpressions+    :: 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 (Pi cs a b c) = Pi cs 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+unsafeSubExpressions _ Bool = pure Bool+unsafeSubExpressions _ (BoolLit b) = pure (BoolLit b)+unsafeSubExpressions f (BoolAnd a b) = BoolAnd <$> f a <*> f b+unsafeSubExpressions f (BoolOr a b) = BoolOr <$> f a <*> f b+unsafeSubExpressions f (BoolEQ a b) = BoolEQ <$> f a <*> f b+unsafeSubExpressions f (BoolNE a b) = BoolNE <$> f a <*> f b+unsafeSubExpressions f (BoolIf a b c) = BoolIf <$> f a <*> f b <*> f c+unsafeSubExpressions _ Bytes = pure Bytes+unsafeSubExpressions _ (BytesLit a) = pure (BytesLit a)+unsafeSubExpressions _ Natural = pure Natural+unsafeSubExpressions _ (NaturalLit n) = pure (NaturalLit n)+unsafeSubExpressions _ NaturalFold = pure NaturalFold+unsafeSubExpressions _ NaturalBuild = pure NaturalBuild+unsafeSubExpressions _ NaturalIsZero = pure NaturalIsZero+unsafeSubExpressions _ NaturalEven = pure NaturalEven+unsafeSubExpressions _ NaturalOdd = pure NaturalOdd+unsafeSubExpressions _ NaturalToInteger = pure NaturalToInteger+unsafeSubExpressions _ NaturalShow = pure NaturalShow+unsafeSubExpressions _ NaturalSubtract = pure NaturalSubtract+unsafeSubExpressions f (NaturalPlus a b) = NaturalPlus <$> f a <*> f b+unsafeSubExpressions f (NaturalTimes a b) = NaturalTimes <$> f a <*> f b+unsafeSubExpressions _ Integer = pure Integer+unsafeSubExpressions _ (IntegerLit n) = pure (IntegerLit n)+unsafeSubExpressions _ IntegerClamp = pure IntegerClamp+unsafeSubExpressions _ IntegerNegate = pure IntegerNegate+unsafeSubExpressions _ IntegerShow = pure IntegerShow+unsafeSubExpressions _ IntegerToDouble = pure IntegerToDouble+unsafeSubExpressions _ Double = pure Double+unsafeSubExpressions _ (DoubleLit n) = pure (DoubleLit n)+unsafeSubExpressions _ DoubleShow = pure DoubleShow+unsafeSubExpressions _ Text = pure Text+unsafeSubExpressions f (TextLit chunks) = TextLit <$> chunkExprs f chunks+unsafeSubExpressions f (TextAppend a b) = TextAppend <$> f a <*> f b+unsafeSubExpressions _ TextReplace = pure TextReplace+unsafeSubExpressions _ TextShow = pure TextShow+unsafeSubExpressions _ Date = pure Date+unsafeSubExpressions _ (DateLiteral a) = pure (DateLiteral a)+unsafeSubExpressions _ DateShow = pure DateShow+unsafeSubExpressions _ Time = pure Time+unsafeSubExpressions _ (TimeLiteral a b) = pure (TimeLiteral a b)+unsafeSubExpressions _ TimeShow = pure TimeShow+unsafeSubExpressions _ TimeZone = pure TimeZone+unsafeSubExpressions _ (TimeZoneLiteral a) = pure (TimeZoneLiteral a)+unsafeSubExpressions _ TimeZoneShow = pure TimeZoneShow+unsafeSubExpressions _ List = pure List+unsafeSubExpressions f (ListLit a b) = ListLit <$> traverse f a <*> traverse f b+unsafeSubExpressions f (ListAppend a b) = ListAppend <$> f a <*> f b+unsafeSubExpressions _ ListBuild = pure ListBuild+unsafeSubExpressions _ ListFold = pure ListFold+unsafeSubExpressions _ ListLength = pure ListLength+unsafeSubExpressions _ ListHead = pure ListHead+unsafeSubExpressions _ ListLast = pure ListLast+unsafeSubExpressions _ ListIndexed = pure ListIndexed+unsafeSubExpressions _ ListReverse = pure ListReverse+unsafeSubExpressions _ Optional = pure Optional+unsafeSubExpressions f (Some a) = Some <$> f a+unsafeSubExpressions _ None = pure None+unsafeSubExpressions f (Union a) = Union <$> traverse (traverse f) a+unsafeSubExpressions f (Combine cs a b c) = Combine cs a <$> f b <*> f c+unsafeSubExpressions f (CombineTypes cs a b) = CombineTypes cs <$> f a <*> f b+unsafeSubExpressions f (Prefer cs a b c) = Prefer cs <$> pure a <*> f b <*> f c+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 (ShowConstructor a) = ShowConstructor <$> f a+unsafeSubExpressions f (Project a b) = Project <$> f a <*> traverse f b+unsafeSubExpressions f (Assert a) = Assert <$> f a+unsafeSubExpressions f (Equivalent cs a b) = Equivalent cs <$> f a <*> f b+unsafeSubExpressions f (With a b c) = With <$> f a <*> pure b <*> f c+unsafeSubExpressions f (ImportAlt l r) = ImportAlt <$> f l <*> f r+unsafeSubExpressions _ (Let {}) = unhandledConstructor "Let"+unsafeSubExpressions _ (Note {}) = unhandledConstructor "Note"+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+unhandledConstructor constructor =+    internalError+        (   "Dhall.Syntax.unsafeSubExpressions: Unhandled "+        <>  constructor+        <>  " construtor"+        )++-- | Remove all `Note` constructors from an `Expr` (i.e. de-`Note`)+--+-- This also remove CharacterSet annotations.+denote :: Expr s a -> Expr t a+denote = \case+    Note _ b -> denote b+    Let a b -> Let (denoteBinding a) (denote b)+    Embed a -> Embed a+    Combine _ _ b c -> Combine Nothing Nothing (denote b) (denote c)+    CombineTypes _ b c -> CombineTypes Nothing (denote b) (denote c)+    Prefer _ a b c -> Lens.over unsafeSubExpressions denote $ Prefer Nothing a b c+    Record a -> Record $ denoteRecordField <$> a+    RecordLit a -> RecordLit $ denoteRecordField <$> a+    Lam _ a b -> Lam Nothing (denoteFunctionBinding a) (denote b)+    Pi _ t a b -> Pi Nothing t (denote a) (denote b)+    Field a (FieldSelection _ b _) -> Field (denote a) (FieldSelection Nothing b Nothing)+    Equivalent _ a b -> Equivalent Nothing (denote a) (denote b)+    expression -> Lens.over unsafeSubExpressions denote expression+  where+    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+{-# INLINE renote #-}++{-| Remove any outermost `Note` constructors++    This is typically used when you want to get the outermost non-`Note`+    constructor without removing internal `Note` constructors+-}+shallowDenote :: Expr s a -> Expr s a+shallowDenote (Note _ e) = shallowDenote e+shallowDenote         e  = e++-- | The set of reserved keywords according to the @keyword@ rule in the grammar+reservedKeywords :: HashSet Text+reservedKeywords =+    Data.HashSet.fromList+        [ "if"+        , "then"+        , "else"+        , "let"+        , "in"+        , "using"+        , "missing"+        , "as"+        , "Infinity"+        , "NaN"+        , "merge"+        , "Some"+        , "toMap"+        , "assert"+        , "forall"+        , "with"+        ]++-- | The set of reserved identifiers for the Dhall language+-- | Contains also all keywords from "reservedKeywords"+reservedIdentifiers :: HashSet Text+reservedIdentifiers = reservedKeywords <>+    Data.HashSet.fromList+        [ -- Builtins according to the `builtin` rule in the grammar+          "Natural/fold"+        , "Natural/build"+        , "Natural/isZero"+        , "Natural/even"+        , "Natural/odd"+        , "Natural/toInteger"+        , "Natural/show"+        , "Natural/subtract"+        , "Integer"+        , "Integer/clamp"+        , "Integer/negate"+        , "Integer/show"+        , "Integer/toDouble"+        , "Integer/show"+        , "Natural/subtract"+        , "Double/show"+        , "List/build"+        , "List/fold"+        , "List/length"+        , "List/head"+        , "List/last"+        , "List/indexed"+        , "List/reverse"+        , "Text/replace"+        , "Text/show"+        , "Date/show"+        , "Time/show"+        , "TimeZone/show"+        , "Bool"+        , "Bytes"+        , "True"+        , "False"+        , "Optional"+        , "None"+        , "Natural"+        , "Integer"+        , "Double"+        , "Text"+        , "Date"+        , "Time"+        , "TimeZone"+        , "List"+        , "Type"+        , "Kind"+        , "Sort"+        ]++{-| `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 cs (FunctionBinding src0 x' src1 src2 _A) b) =+    Lam cs (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 cs x' _A _B) = Pi cs 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++_ERROR :: String+_ERROR = "\ESC[1;31mError\ESC[0m"++{-| Utility function used to throw internal errors that should never happen+    (in theory) but that are not enforced by the type system+-}+internalError :: Data.Text.Text -> forall b . b+internalError text = error (unlines+    [ _ERROR <> ": Compiler bug                                                        "+    , "                                                                                "+    , "Explanation: This error message means that there is a bug in the Dhall compiler."+    , "You didn't do anything wrong, but if you would like to see this problem fixed   "+    , "then you should report the bug at:                                              "+    , "                                                                                "+    , "https://github.com/dhall-lang/dhall-haskell/issues                              "+    , "                                                                                "+    , "Please include the following text in your bug report:                           "+    , "                                                                                "+    , "```                                                                             "+    , Data.Text.unpack text <> "                                                       "+    , "```                                                                             "+    ] )
+ src/Dhall/Syntax/Operations.hs-boot view
@@ -0,0 +1,5 @@+module Dhall.Syntax.Operations where++import Dhall.Syntax.Expr (Expr)++unsafeSubExpressions :: Applicative f => (Expr s a -> f (Expr t b)) -> Expr s a -> f (Expr t b)
+ src/Dhall/Syntax/RecordField.hs view
@@ -0,0 +1,93 @@+{-# LANGUAGE DeriveGeneric #-}++module Dhall.Syntax.RecordField+    ( RecordField(..)+    , makeRecordField++      -- * Optics+    , recordFieldExprs+    ) where++import {-# SOURCE #-} Dhall.Syntax.Expr (Expr)+import                GHC.Generics      (Generic)++-- | Record the field of a record-type and record-literal expression.+-- The reason why we use the same ADT for both of them is because they store+-- the same information.+--+-- For example,+--+-- > { {- A -} x {- B -} : {- C -} T }+--+-- ... or+--+-- > { {- A -} x {- B -} = {- C -} T }+--+-- will be instantiated as follows:+--+-- * @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.+--+-- 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+    { recordFieldSrc0  :: Maybe s+    , recordFieldValue :: Expr s a+    , recordFieldSrc1  :: Maybe s+    , recordFieldSrc2  :: Maybe s+    } deriving Generic++-- | Construct a 'RecordField' with no src information+makeRecordField :: Expr s a -> RecordField s a+makeRecordField e = RecordField Nothing e Nothing Nothing++{-| Traverse over the immediate 'Expr' children in a 'RecordField'.+-}+recordFieldExprs+    :: Applicative f+    => (Expr s a -> f (Expr s b))+    -> RecordField s a -> f (RecordField s b)+recordFieldExprs f (RecordField s0 e s1 s2) =+    RecordField+        <$> pure s0+        <*> f e+        <*> pure s1+        <*> pure s2+{-# INLINABLE recordFieldExprs #-}
+ src/Dhall/Syntax/Types.hs view
@@ -0,0 +1,55 @@+{-# LANGUAGE DeriveGeneric #-}++module Dhall.Syntax.Types+    ( DhallDouble(..)+    , PreferAnnotation(..)+    , FieldSelection(..)+    , makeFieldSelection+    , WithComponent(..)+    ) where++import Data.Text    (Text)+import GHC.Generics (Generic)++-- | This wrapper around 'Prelude.Double' exists for its 'Eq' instance which is+-- defined via the binary encoding of Dhall @Double@s.+newtype DhallDouble = DhallDouble { getDhallDouble :: Double }+    deriving Generic++-- | Used to record the origin of a @//@ operator (i.e. from source code or a+-- product of desugaring)+data PreferAnnotation+    = PreferFromSource+    | PreferFromCompletion+    deriving Generic++-- | 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 Dhall.Src.Src' (@s = 'Dhall.Src.Src'@) to be consistent with similar+-- data types such as 'Dhall.Syntax.Binding.Binding', for example.+data FieldSelection s = FieldSelection+    { fieldSelectionSrc0 :: Maybe s+    , fieldSelectionLabel :: !Text+    , fieldSelectionSrc1 :: Maybe s+    } deriving Generic++-- | Smart constructor for 'FieldSelection' with no src information+makeFieldSelection :: Text -> FieldSelection s+makeFieldSelection t = FieldSelection Nothing t Nothing++-- | A path component for a @with@ expression+data WithComponent = WithLabel Text | WithQuestion+    deriving Generic
+ src/Dhall/Syntax/Types.hs-boot view
@@ -0,0 +1,14 @@+{-# LANGUAGE StandaloneKindSignatures #-}++module Dhall.Syntax.Types where++import Data.Kind (Type)++data DhallDouble++data PreferAnnotation++type FieldSelection :: Type -> Type+data FieldSelection s++data WithComponent
+ src/Dhall/Syntax/Var.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE DeriveGeneric #-}++module Dhall.Syntax.Var+    ( Var(..)+    ) where++import Data.String  (IsString (..))+import Data.Text    (Text)+import GHC.Generics (Generic)++{-| Label for a bound variable++    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+    nearest bound variable and the index increases by one for each bound+    variable of the same name going outward.  The following diagram may help:++>                               ┌──refers to──┐+>                               │             │+>                               v             │+> λ(x : Type) → λ(y : Type) → λ(x : Type) → x@0+>+> ┌─────────────────refers to─────────────────┐+> │                                           │+> v                                           │+> λ(x : Type) → λ(y : Type) → λ(x : Type) → x@1++    This `Int` behaves like a De Bruijn index in the special case where all+    variables have the same name.++    You can optionally omit the index if it is @0@:++>                               ┌─refers to─┐+>                               │           │+>                               v           │+> λ(x : Type) → λ(y : Type) → λ(x : Type) → x++    Zero indices are omitted when pretty-printing @Var@s and non-zero indices+    appear as a numeric suffix.+-}+data Var = V Text !Int+    deriving Generic++instance IsString Var where+    fromString str = V (fromString str) 0
src/Dhall/TH.hs view
@@ -1,4 +1,6 @@+{-# LANGUAGE CPP               #-} {-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE FlexibleContexts  #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PatternGuards     #-} {-# LANGUAGE RecordWildCards   #-}@@ -6,25 +8,36 @@  -- | Template Haskell utilities module Dhall.TH-    ( -- * Template Haskell+    ( -- * Embedding Dhall in Haskell       staticDhallExpression+    , dhall+      -- * Generating Haskell from Dhall expressions     , makeHaskellTypeFromUnion     , makeHaskellTypes+    , makeHaskellTypesWith     , HaskellType(..)+    , GenerateOptions(..)+    , defaultGenerateOptions     ) where +import Control.Monad             (forM_)+import Data.Bifunctor            (first) import Data.Text                 (Text)-import Data.Text.Prettyprint.Doc (Pretty) import Dhall                     (FromDhall, ToDhall)-import Dhall.Syntax              (Expr (..))+import Dhall.Syntax              (Expr (..), FunctionBinding (..), Var (..)) import GHC.Generics              (Generic)-import Language.Haskell.TH.Quote (dataToExpQ)+import Language.Haskell.TH.Quote (QuasiQuoter (..), dataToExpQ)+import Lens.Micro.Extras         (view)+import Prettyprinter             (Pretty)  import Language.Haskell.TH.Syntax     ( Bang (..)+    , Body (..)     , Con (..)     , Dec (..)     , Exp (..)+    , Match (..)+    , Pat (..)     , Q     , SourceStrictness (..)     , SourceUnpackedness (..)@@ -33,20 +46,25 @@  import Language.Haskell.TH.Syntax (DerivClause (..), DerivStrategy (..)) -import qualified Data.List                               as List-import qualified Data.Text                               as Text-import qualified Data.Text.Prettyprint.Doc.Render.String as Pretty-import qualified Data.Typeable                           as Typeable+import qualified Data.List                   as List+import qualified Data.Map                    as Map+import qualified Data.Set                    as Set+import qualified Data.Text                   as Text+import qualified Data.Time                   as Time+import qualified Data.Typeable               as Typeable import qualified Dhall-import qualified Dhall.Core                              as Core+import qualified Dhall.Core                  as Core+import qualified Dhall.Import import qualified Dhall.Map import qualified Dhall.Pretty import qualified Dhall.Util import qualified GHC.IO.Encoding-import qualified Language.Haskell.TH.Syntax              as Syntax+import qualified Language.Haskell.TH.Syntax  as TH import qualified Numeric.Natural+import qualified Prettyprinter.Render.String as Pretty import qualified System.IO + {-| This fully resolves, type checks, and normalizes the expression, so the     resulting AST is self-contained. @@ -73,23 +91,61 @@ -} staticDhallExpression :: Text -> Q Exp staticDhallExpression text = do-    Syntax.runIO (GHC.IO.Encoding.setLocaleEncoding System.IO.utf8)+    TH.runIO (GHC.IO.Encoding.setLocaleEncoding System.IO.utf8) -    expression <- Syntax.runIO (Dhall.inputExpr text)+    (expression, status) <- TH.runIO $ do+        parsed <- Dhall.parseWithSettings Dhall.defaultInputSettings text +        (resolved, status) <- Dhall.resolveAndStatusWithSettings Dhall.defaultInputSettings parsed++        _ <- Dhall.typecheckWithSettings Dhall.defaultInputSettings resolved++        let normalized = Dhall.normalizeWithSettings Dhall.defaultInputSettings resolved++        pure (normalized, status)++    forM_ (Dhall.Map.keys (view Dhall.Import.cache status)) $ \chained ->+        case Dhall.Import.chainedImport chained of+            Core.Import+                { importHashed = Core.ImportHashed+                    { importType = Core.Local prefix file+                    }+                } -> do+                    fp <- Dhall.Import.localToPath prefix file+                    TH.addDependentFile fp+            _ -> return ()+     dataToExpQ (fmap liftText . Typeable.cast) expression   where     -- A workaround for a problem in TemplateHaskell (see     -- https://stackoverflow.com/questions/38143464/cant-find-inerface-file-declaration-for-variable)-    liftText = fmap (AppE (VarE 'Text.pack)) . Syntax.lift . Text.unpack+    liftText = fmap (AppE (VarE 'Text.pack)) . TH.lift . Text.unpack +{-| A quasi-quoter for Dhall expressions.++    This quoter is build on top of 'staticDhallExpression'. Therefore consult the+    documentation of that function for further information.++    This quoter is meant to be used in expression context only; Other contexts+    like pattern contexts or declaration contexts are not supported and will+    result in an error.+-}+dhall :: QuasiQuoter+dhall = QuasiQuoter+    { quoteExp = staticDhallExpression . Text.pack+    , quotePat = const $ error "dhall quasi-quoter: Quoting patterns is not supported!"+    , quoteType = const $ error "dhall quasi-quoter: Quoting types is not supported!"+    , quoteDec = const $ error "dhall quasi-quoter: Quoting declarations is not supported!"+    }+ {-| Convert a Dhall type to a Haskell type that does not require any new     data declarations beyond the data declarations supplied as the first     argument -} toNestedHaskellType     :: (Eq a, Pretty a)-    => [HaskellType (Expr s a)]+    => [Var]+    -> [HaskellType (Expr s a)]     -- ^ All Dhall-derived data declarations     --     -- Used to replace complex types with references to one of these@@ -97,8 +153,40 @@     -> Expr s a     -- ^ Dhall expression to convert to a simple Haskell type     -> Q Type-toNestedHaskellType haskellTypes = loop+toNestedHaskellType typeParams haskellTypes = loop   where+    predicate dhallType haskellType = Core.judgmentallyEqual (code haskellType) dhallType++    document dhallType =+      mconcat+      [ "Unsupported nested type\n"+      , "                                                                                \n"+      , "Explanation: Not all Dhall types can be nested within Haskell datatype          \n"+      , "declarations.  Specifically, only the following simple Dhall types are supported\n"+      , "as a nested type inside of a data declaration:                                  \n"+      , "                                                                                \n"+      , "• ❰Bool❱                                                                        \n"+      , "• ❰Double❱                                                                      \n"+      , "• ❰Integer❱                                                                     \n"+      , "• ❰Natural❱                                                                     \n"+      , "• ❰Text❱                                                                        \n"+      , "• ❰Date❱                                                                        \n"+      , "• ❰TimeOfDay❱                                                                   \n"+      , "• ❰TimeZone❱                                                                    \n"+      , "• ❰List a❱     (where ❰a❱ is also a valid nested type)                          \n"+      , "• ❰Optional a❱ (where ❰a❱ is also a valid nested type)                          \n"+      , "• Another matching datatype declaration                                         \n"+      , "• A bound type variable                                                         \n"+      , "                                                                                \n"+      , "The Haskell datatype generation logic encountered the following Dhall type:     \n"+      , "                                                                                \n"+      , " " <> Dhall.Util.insert dhallType <> "\n"+      , "                                                                                \n"+      , "... which did not fit any of the above criteria."+      ]++    message dhallType = Pretty.renderString (Dhall.Pretty.layout (document dhallType))+     loop dhallType = case dhallType of         Bool ->             return (ConT ''Bool)@@ -115,6 +203,15 @@         Text ->             return (ConT ''Text) +        Date ->+            return (ConT ''Time.Day)++        Time ->+            return (ConT ''Time.TimeOfDay)++        TimeZone ->+            return (ConT ''Time.TimeZone)+         App List dhallElementType -> do             haskellElementType <- loop dhallElementType @@ -125,126 +222,168 @@              return (AppT (ConT ''Maybe) haskellElementType) -        _   | Just haskellType <- List.find predicate haskellTypes -> do-                let name = Syntax.mkName (Text.unpack (typeName haskellType))+        App dhallAppType dhallElementType -> do+            haskellAppType <- loop dhallAppType+            haskellElementType <- loop dhallElementType -                return (ConT name) -            | otherwise -> do-            let document =-                    mconcat-                    [ "Unsupported nested type\n"-                    , "                                                                                \n"-                    , "Explanation: Not all Dhall types can be nested within Haskell datatype          \n"-                    , "declarations.  Specifically, only the following simple Dhall types are supported\n"-                    , "as a nested type inside of a data declaration:                                  \n"-                    , "                                                                                \n"-                    , "• ❰Bool❱                                                                        \n"-                    , "• ❰Double❱                                                                      \n"-                    , "• ❰Integer❱                                                                     \n"-                    , "• ❰Natural❱                                                                     \n"-                    , "• ❰Text❱                                                                        \n"-                    , "• ❰List a❱     (where ❰a❱ is also a valid nested type)                          \n"-                    , "• ❰Optional a❱ (where ❰a❱ is also a valid nested type)                          \n"-                    , "• Another matching datatype declaration                                         \n"-                    , "                                                                                \n"-                    , "The Haskell datatype generation logic encountered the following Dhall type:     \n"-                    , "                                                                                \n"-                    , " " <> Dhall.Util.insert dhallType <> "\n"-                    , "                                                                                \n"-                    , "... which did not fit any of the above criteria."-                    ]+            return (AppT haskellAppType haskellElementType) -            let message = Pretty.renderString (Dhall.Pretty.layout document)+        Var v+            | Just (V param index) <- List.find (v ==) typeParams -> do+                let name = TH.mkName $ (Text.unpack param) ++ (show index) -            fail message-          where-            predicate haskellType =-                Core.judgmentallyEqual (code haskellType) dhallType+                return (VarT name) -derivingClauses :: [DerivClause]-derivingClauses =-    [ DerivClause (Just StockStrategy) [ ConT ''Generic ]-    , DerivClause (Just AnyclassStrategy) [ ConT ''FromDhall, ConT ''ToDhall ]-    ]+            | otherwise -> fail $ message v +        _   | Just haskellType <- List.find (predicate dhallType) haskellTypes -> do+                let name = TH.mkName (Text.unpack (typeName haskellType))++                return (ConT name)+            | otherwise -> fail $ message dhallType++-- | A deriving clause for `Generic`.+derivingGenericClause :: DerivClause+derivingGenericClause = DerivClause (Just StockStrategy) [ ConT ''Generic ]++-- | Generates a `FromDhall` instances.+fromDhallInstance+    :: TH.Name -- ^ The name of the type the instances is for+    -> Q Exp       -- ^ A TH splice generating some `Dhall.InterpretOptions`+    -> Q [Dec]+fromDhallInstance n interpretOptions = [d|+    instance FromDhall $(pure $ ConT n) where+        autoWith = Dhall.genericAutoWithInputNormalizer $(interpretOptions)+    |]++-- | Generates a `ToDhall` instances.+toDhallInstance+    :: TH.Name -- ^ The name of the type the instances is for+    -> Q Exp       -- ^ A TH splice generating some `Dhall.InterpretOptions`+    -> Q [Dec]+toDhallInstance n interpretOptions = [d|+    instance ToDhall $(pure $ ConT n) where+        injectWith = Dhall.genericToDhallWithInputNormalizer $(interpretOptions)+    |]+ -- | Convert a Dhall type to the corresponding Haskell datatype declaration toDeclaration     :: (Eq a, Pretty a)-    => [HaskellType (Expr s a)]+    => GenerateOptions+    -> [HaskellType (Expr s a)]     -> HaskellType (Expr s a)-    -> Q Dec-toDeclaration haskellTypes MultipleConstructors{..} =-    case code of-        Union kts -> do-            let name = Syntax.mkName (Text.unpack typeName)+    -> Q [Dec]+toDeclaration generateOptions@GenerateOptions{..} haskellTypes typ =+    case typ of+        SingleConstructor{..} -> uncurry (fromSingle typeName constructorName) $ getTypeParams code+        MultipleConstructors{..} -> uncurry (fromMulti typeName) $ getTypeParams code+    where+        getTypeParams = first numberConsecutive .  getTypeParams_ [] -            constructors <- traverse (toConstructor haskellTypes typeName) (Dhall.Map.toList kts )+        getTypeParams_ acc (Lam _ (FunctionBinding _ v _ _ _) rest) = getTypeParams_ (v:acc) rest+        getTypeParams_ acc rest = (acc, rest) -            return (DataD [] name [] Nothing constructors derivingClauses)+        derivingClauses = [ derivingGenericClause | generateFromDhallInstance || generateToDhallInstance ] -        _ -> do-            let document =-                    mconcat-                    [ "Dhall.TH.makeHaskellTypes: Not a union type\n"-                    , "                                                                                \n"-                    , "Explanation: This function expects the ❰code❱ field of ❰MultipleConstructors❱ to\n"-                    , "evaluate to a union type.                                                       \n"-                    , "                                                                                \n"-                    , "For example, this is a valid Dhall union type that this function would accept:  \n"-                    , "                                                                                \n"-                    , "                                                                                \n"-                    , "    ┌──────────────────────────────────────────────────────────────────┐        \n"-                    , "    │ Dhall.TH.makeHaskellTypes (MultipleConstructors \"T\" \"< A | B >\") │        \n"-                    , "    └──────────────────────────────────────────────────────────────────┘        \n"-                    , "                                                                                \n"-                    , "                                                                                \n"-                    , "... which corresponds to this Haskell type declaration:                         \n"-                    , "                                                                                \n"-                    , "                                                                                \n"-                    , "    ┌────────────────┐                                                          \n"-                    , "    │ data T = A | B │                                                          \n"-                    , "    └────────────────┘                                                          \n"-                    , "                                                                                \n"-                    , "                                                                                \n"-                    , "... but the following Dhall type is rejected due to being a bare record type:   \n"-                    , "                                                                                \n"-                    , "                                                                                \n"-                    , "    ┌──────────────────────────────────────────────┐                            \n"-                    , "    │ Dhall.TH.makeHaskellTypes \"T\" \"{ x : Bool }\" │  Not valid                 \n"-                    , "    └──────────────────────────────────────────────┘                            \n"-                    , "                                                                                \n"-                    , "                                                                                \n"-                    , "The Haskell datatype generation logic encountered the following Dhall type:     \n"-                    , "                                                                                \n"-                    , " " <> Dhall.Util.insert code <> "\n"-                    , "                                                                                \n"-                    , "... which is not a union type."-                    ]+        interpretOptions = generateToInterpretOptions generateOptions typ -            let message = Pretty.renderString (Dhall.Pretty.layout document)+#if MIN_VERSION_template_haskell(2,21,0)+        toTypeVar (V n i) = TH.PlainTV (TH.mkName (Text.unpack n ++ show i)) TH.BndrReq+#elif MIN_VERSION_template_haskell(2,17,0)+        toTypeVar (V n i) = TH.PlainTV (TH.mkName (Text.unpack n ++ show i)) ()+#else+        toTypeVar (V n i) = TH.PlainTV (TH.mkName (Text.unpack n ++ show i))+#endif -            fail message-toDeclaration haskellTypes SingleConstructor{..} = do-    let name = Syntax.mkName (Text.unpack typeName)+        toDataD typeName typeParams constructors = do+            let name = TH.mkName (Text.unpack typeName) -    constructor <- toConstructor haskellTypes typeName (constructorName, Just code)+            let params = fmap toTypeVar typeParams -    return (DataD [] name [] Nothing [constructor] derivingClauses)+            fmap concat . sequence $+                [pure [DataD [] name params Nothing constructors derivingClauses]] <>+                [ fromDhallInstance name interpretOptions | generateFromDhallInstance ] <>+                [ toDhallInstance name interpretOptions | generateToDhallInstance ] +        fromSingle typeName constructorName typeParams dhallType = do+            constructor <- toConstructor typeParams generateOptions haskellTypes typeName (constructorName, Just dhallType)++            toDataD typeName typeParams [constructor]++        fromMulti typeName typeParams dhallType = case dhallType of+            Union kts -> do+                constructors <- traverse (toConstructor typeParams generateOptions haskellTypes typeName) (Dhall.Map.toList kts)++                toDataD typeName typeParams constructors++            _ -> fail $ message dhallType++        message dhallType = Pretty.renderString (Dhall.Pretty.layout $ document dhallType)++        document dhallType =+            mconcat+                [ "Dhall.TH.makeHaskellTypes: Not a union type\n"+                , "                                                                                \n"+                , "Explanation: This function expects the ❰code❱ field of ❰MultipleConstructors❱ to\n"+                , "evaluate to a union type.                                                       \n"+                , "                                                                                \n"+                , "For example, this is a valid Dhall union type that this function would accept:  \n"+                , "                                                                                \n"+                , "                                                                                \n"+                , "    ┌──────────────────────────────────────────────────────────────────┐        \n"+                , "    │ Dhall.TH.makeHaskellTypes (MultipleConstructors \"T\" \"< A | B >\") │        \n"+                , "    └──────────────────────────────────────────────────────────────────┘        \n"+                , "                                                                                \n"+                , "                                                                                \n"+                , "... which corresponds to this Haskell type declaration:                         \n"+                , "                                                                                \n"+                , "                                                                                \n"+                , "    ┌────────────────┐                                                          \n"+                , "    │ data T = A | B │                                                          \n"+                , "    └────────────────┘                                                          \n"+                , "                                                                                \n"+                , "                                                                                \n"+                , "... but the following Dhall type is rejected due to being a bare record type:   \n"+                , "                                                                                \n"+                , "                                                                                \n"+                , "    ┌──────────────────────────────────────────────┐                            \n"+                , "    │ Dhall.TH.makeHaskellTypes \"T\" \"{ x : Bool }\" │  Not valid                 \n"+                , "    └──────────────────────────────────────────────┘                            \n"+                , "                                                                                \n"+                , "                                                                                \n"+                , "The Haskell datatype generation logic encountered the following Dhall type:     \n"+                , "                                                                                \n"+                , " " <> Dhall.Util.insert dhallType <> "\n"+                , "                                                                                \n"+                , "... which is not a union type."+                ]++-- | Number each variable, starting at 0+numberConsecutive :: [Text.Text] -> [Var]+numberConsecutive = snd . List.mapAccumR go Map.empty . reverse+  where+      go m k =+          let (i, m') = Map.updateLookupWithKey (\_ j -> Just $ j + 1) k m+          in maybe ((Map.insert k 0 m'), (V k 0)) (\i' -> (m', (V k i'))) i+ -- | Convert a Dhall type to the corresponding Haskell constructor toConstructor     :: (Eq a, Pretty a)-    => [HaskellType (Expr s a)]+    => [Var]+    -> GenerateOptions+    -> [HaskellType (Expr s a)]     -> Text     -- ^ typeName     -> (Text, Maybe (Expr s a))     -- ^ @(constructorName, fieldType)@     -> Q Con-toConstructor haskellTypes outerTypeName (constructorName, maybeAlternativeType) = do-    let name = Syntax.mkName (Text.unpack constructorName)+toConstructor typeParams GenerateOptions{..} haskellTypes outerTypeName (constructorName, maybeAlternativeType) = do+    let name = TH.mkName (Text.unpack $ constructorModifier constructorName) -    let bang = Bang NoSourceUnpackedness NoSourceStrictness+    let strictness = if makeStrict then SourceStrict else NoSourceStrictness +    let bang = Bang NoSourceUnpackedness strictness+     case maybeAlternativeType of         Just dhallType             | let predicate haskellType =@@ -252,22 +391,22 @@                     && typeName haskellType /= outerTypeName             , Just haskellType <- List.find predicate haskellTypes -> do                 let innerName =-                        Syntax.mkName (Text.unpack (typeName haskellType))+                        TH.mkName (Text.unpack (typeName haskellType))                  return (NormalC name [ (bang, ConT innerName) ])          Just (Record kts) -> do             let process (key, dhallFieldType) = do-                    haskellFieldType <- toNestedHaskellType haskellTypes dhallFieldType+                    haskellFieldType <- toNestedHaskellType typeParams haskellTypes dhallFieldType -                    return (Syntax.mkName (Text.unpack key), bang, haskellFieldType)+                    return (TH.mkName (Text.unpack $ fieldModifier key), bang, haskellFieldType)              varBangTypes <- traverse process (Dhall.Map.toList $ Core.recordFieldValue <$> kts)              return (RecC name varBangTypes)          Just dhallAlternativeType -> do-            haskellAlternativeType <- toNestedHaskellType haskellTypes dhallAlternativeType+            haskellAlternativeType <- toNestedHaskellType typeParams haskellTypes dhallAlternativeType              return (NormalC name [ (bang, haskellAlternativeType) ]) @@ -298,17 +437,18 @@ makeHaskellTypeFromUnion typeName code =     makeHaskellTypes [ MultipleConstructors{..} ] --- | Used by `makeHaskellTypes` to specify how to generate Haskell types+-- | Used by `makeHaskellTypes` and `makeHaskellTypesWith` to specify how to+-- generate Haskell types. data HaskellType code     -- | Generate a Haskell type with more than one constructor from a Dhall-    -- union type+    -- union type.     = MultipleConstructors         { typeName :: Text         -- ^ Name of the generated Haskell type         , code :: code         -- ^ Dhall code that evaluates to a union type         }-    -- | Generate a Haskell type with one constructor from any Dhall type+    -- | Generate a Haskell type with one constructor from any Dhall type.     --     -- To generate a constructor with multiple named fields, supply a Dhall     -- record type.  This does not support more than one anonymous field.@@ -322,8 +462,88 @@         }     deriving (Functor, Foldable, Traversable) +-- | This data type holds various options that let you control several aspects+-- how Haskell code is generated. In particular you can+--+--   * disable the generation of `FromDhall`/`ToDhall` instances.+--   * modify how a Dhall union field translates to a Haskell data constructor.+data GenerateOptions = GenerateOptions+    { constructorModifier :: Text -> Text+    -- ^ How to map a Dhall union field name to a Haskell constructor.+    -- Note: The `constructorName` of `SingleConstructor` will be passed to this function, too.+    , fieldModifier :: Text -> Text+    -- ^ How to map a Dhall record field names to a Haskell record field names.+    , generateFromDhallInstance :: Bool+    -- ^ Generate a `FromDhall` instance for the Haskell type+    , generateToDhallInstance :: Bool+    -- ^ Generate a `ToDhall` instance for the Haskell type+    , makeStrict :: Bool+    -- ^ Make all fields strict.+    }++-- | A default set of options used by `makeHaskellTypes`. That means:+--+--     * Constructors and fields are passed unmodified.+--     * Both `FromDhall` and `ToDhall` instances are generated.+--+--   Note: `From/ToDhall` should be `False` if importing higher-kinded types.+--   In these cases one should use a standalone declaration.+defaultGenerateOptions :: GenerateOptions+defaultGenerateOptions = GenerateOptions+    { constructorModifier = id+    , fieldModifier = id+    , generateFromDhallInstance = True+    , generateToDhallInstance = True+    , makeStrict = False+    }++-- | This function generates `Dhall.InterpretOptions` that can be used for the+--   marshalling of the Haskell type generated according to the `GenerateOptions`.+--   I.e. those `Dhall.InterpretOptions` reflect the mapping done by+--   `constructorModifier` and `fieldModifier` on the value level.+generateToInterpretOptions :: GenerateOptions -> HaskellType (Expr s a) -> Q Exp+generateToInterpretOptions GenerateOptions{..} haskellType = [| Dhall.InterpretOptions+    { Dhall.fieldModifier = \ $(pure nameP) ->+        $(toCases fieldModifier $ fields haskellType)+    , Dhall.constructorModifier = \ $(pure nameP) ->+        $(toCases constructorModifier $ constructors haskellType)+    , Dhall.singletonConstructors = Dhall.singletonConstructors Dhall.defaultInterpretOptions+    }|]+    where+        constructors :: HaskellType (Expr s a) -> [Text]+        constructors SingleConstructor{..} = [constructorName]+        constructors MultipleConstructors{..} | Union kts <- code = Dhall.Map.keys kts+        constructors _ = []++        fields :: HaskellType (Expr s a) -> [Text]+        fields SingleConstructor{..} | Record kts <- code = Dhall.Map.keys kts+        fields MultipleConstructors{..} | Union kts <- code = Set.toList $ mconcat+            [ Dhall.Map.keysSet kts'+            | (_, Just (Record kts')) <- Dhall.Map.toList kts+            ]+        fields _ = []++        toCases :: (Text -> Text) -> [Text] -> Q Exp+        toCases f xs = do+            err <- [| Core.internalError $ "Unmatched " <> Text.pack (show $(pure nameE)) |]+            pure $ CaseE nameE $ map mkMatch xs <> [Match WildP (NormalB err) []]+            where+                mkMatch n = Match (textToPat $ f n) (NormalB $ textToExp n) []++        nameE :: Exp+        nameE = TH.VarE $ TH.mkName "n"++        nameP :: Pat+        nameP = TH.VarP $ TH.mkName "n"++        textToExp :: Text -> Exp+        textToExp = TH.LitE . TH.StringL . Text.unpack++        textToPat :: Text -> Pat+        textToPat = TH.LitP . TH.StringL . Text.unpack+ -- | Generate a Haskell datatype declaration with one constructor from a Dhall--- type+-- type. -- -- This comes in handy if you need to keep Dhall types and Haskell types in -- sync.  You make the Dhall types the source of truth and use Template Haskell@@ -398,9 +618,18 @@ -- > deriving instance Ord  Employee -- > deriving instance Show Employee makeHaskellTypes :: [HaskellType Text] -> Q [Dec]-makeHaskellTypes haskellTypes = do-    Syntax.runIO (GHC.IO.Encoding.setLocaleEncoding System.IO.utf8)+makeHaskellTypes = makeHaskellTypesWith defaultGenerateOptions -    haskellTypes' <- traverse (traverse (Syntax.runIO . Dhall.inputExpr)) haskellTypes+-- | Like `makeHaskellTypes`, but with the ability to customize the generated+-- Haskell code by passing `GenerateOptions`.+--+-- For instance, `makeHaskellTypes` is implemented using this function:+--+-- > makeHaskellTypes = makeHaskellTypesWith defaultGenerateOptions+makeHaskellTypesWith :: GenerateOptions -> [HaskellType Text] -> Q [Dec]+makeHaskellTypesWith generateOptions haskellTypes = do+    TH.runIO (GHC.IO.Encoding.setLocaleEncoding System.IO.utf8) -    traverse (toDeclaration haskellTypes') haskellTypes'+    haskellTypes' <- traverse (traverse (TH.runIO . Dhall.inputExpr)) haskellTypes++    concat <$> traverse (toDeclaration generateOptions haskellTypes') haskellTypes'
src/Dhall/Tutorial.hs view
@@ -1,4 +1,5 @@ {-# OPTIONS_GHC -fno-warn-unused-imports #-}+{-# LANGUAGE CPP #-}  {-| Dhall is a programming language specialized for configuration files.  This     module contains a tutorial explaining how to author configuration files@@ -375,13 +376,23 @@ -- -- ... and you can reference that expression either directly: --+#if defined(WITH_HTTP) && defined(USE_HTTP_CLIENT_TLS) && defined(NETWORK_TESTS) -- >>> input auto "https://raw.githubusercontent.com/dhall-lang/dhall-haskell/18e4e9a18dc53271146df3ccf5b4177c3552236b/examples/True" :: IO Bool -- True+#else+-- > >>> input auto "https://raw.githubusercontent.com/dhall-lang/dhall-haskell/18e4e9a18dc53271146df3ccf5b4177c3552236b/examples/True" :: IO Bool+-- > True+#endif -- -- ... or inside of a larger expression: --+#if defined(WITH_HTTP) && defined(USE_HTTP_CLIENT_TLS) && defined(NETWORK_TESTS) -- >>> input auto "False == https://raw.githubusercontent.com/dhall-lang/dhall-haskell/18e4e9a18dc53271146df3ccf5b4177c3552236b/examples/True" :: IO Bool -- False+#else+-- > >>> input auto "False == https://raw.githubusercontent.com/dhall-lang/dhall-haskell/18e4e9a18dc53271146df3ccf5b4177c3552236b/examples/True" :: IO Bool+-- > False+#endif -- -- You're not limited to hosting Dhall expressions on GitHub.  You can host a -- Dhall expression anywhere that you can host UTF8-encoded text on the web,@@ -1619,7 +1630,7 @@ -- > let replicate = https://prelude.dhall-lang.org/List/replicate -- > in  replicate 5 -- > $--- > $ dhall freeze --inplace ./foo.dhall+-- > $ dhall freeze ./foo.dhall -- > $ cat ./foo.dhall -- > let replicate = -- >       https://prelude.dhall-lang.org/List/replicate sha256:d4250b45278f2d692302489ac3e78280acb238d27541c837ce46911ff3baa347@@ -1633,7 +1644,7 @@ -- record might be the contents of a software license: -- -- > { package = "dhall"--- > , author  = "Gabriel Gonzalez"+-- > , author  = "Gabriella Gonzalez" -- > , license = ./LICENSE -- > } --@@ -1642,7 +1653,7 @@ -- -- > $ cat LICENSE -- > ''--- > Copyright (c) 2017 Gabriel Gonzalez+-- > Copyright (c) 2017 Gabriella Gonzalez -- > All rights reserved. -- > -- > ...@@ -1657,14 +1668,14 @@ -- end of the import, like this: -- -- > { package = "dhall"--- > , author  = "Gabriel Gonzalez"+-- > , author  = "Gabriella Gonzalez" -- > , license = ./LICENSE as Text -- > } -- -- ... and then you can use the original text file unmodified: -- -- > $ cat LICENSE--- > Copyright (c) 2017 Gabriel Gonzalez+-- > Copyright (c) 2017 Gabriella Gonzalez -- > All rights reserved. -- > -- > ...@@ -1744,10 +1755,9 @@ -- >       (List (List Natural)) -- >       (replicate 5 (List Natural) (replicate 5 Natural 1)) ----- You can also use the formatter to modify files in place using the--- @--inplace@ flag (i.e. for formatting source code):+-- You can also use the formatter to modify files in place: ----- > $ dhall format --inplace ./unformatted+-- > $ dhall format ./unformatted -- -- Carefully note that the code formatter does not preserve all comments. -- Currently, the formatter only preserves two types of comments:@@ -1847,7 +1857,7 @@ -- You can find an up-to-date list of available built-in functions and operators -- here: ----- <https://github.com/dhall-lang/dhall-lang/wiki/Built-in-types%2C-functions%2C-and-operators Built-in types, functions, and operators>+-- <https://docs.dhall-lang.org/references/Built-in-types.html>  -- $caveats --@@ -1872,9 +1882,13 @@ -- > -- > (input):1:1 ----- In fact, there are no built-in functions for @Integer@s (or @Double@s) other--- than @Integer/show@ and @Double/show@.  As far as the language is concerned--- they are opaque values that can only be shuffled around but not used in any+-- There are no built-in functions for @Integer@ arithmetic; however, conversion+-- to and from @Natural@s is possible usinng @Integer/clamp@, @Integer/negate@+-- and @Natural/toInteger@.+--+-- For @Double@s the situation is even more extreme: there are no built-in+-- functions other than @Double/show@. As far as the language is concerned they+-- are opaque values that can only be shuffled around but not used in any -- meaningful way until they have been loaded into Haskell. -- -- Second, the equality @(==)@ and inequality @(!=)@ operators only work on@@ -1969,6 +1983,7 @@ -- $substitutions -- -- Substitutions are another way to extend the language.+-- -- Suppose we have the following Haskell datatype: -- -- > data Result = Failure Integer | Success String@@ -1980,28 +1995,15 @@ -- -- > -- example.dhall -- >--- > let Result = < Failure : Integer | Success Text >--- > in Result.Failure 1+-- > let Result = < Failure : Integer | Success : Text >+-- > in Result.Failure +1 -- -- Right now it is quite easy to keep these two definitions (the one in Haskell source and the one in the Dhall file) synchronized: -- If we implement a new feature in the Haskell source we update the corresponding type in the Dhall file. -- But what happens if our application is growing and our Result type contains e.g. 10 unions with possible types embedded in it?--- Maintaining the code will get tedious. Luckily we can extract the correct Dhall type from the Haskell definition: ----- > resultDecoder :: Dhall.Decoder Result--- > resultDecoder = Dhall.auto--- >--- > resultType :: Expr Src Void--- > resultType = Dhall.expected resultDecoder--- >--- > resultTypeString :: String--- > resultTypeString = show $ pretty resultType------ Now we just have to inject that type into the Dhall code and we are done. One common way to do that is to wrap the import of example.dhall in a let expression:------ > Dhall.input (Dhall.auto :: Dhall.Decoder Result) ("let Result = " ++ Data.Text.pack resultTypeString ++ " in ./example.dhall")------ Now we can omit the definition of Result in our example.dhall file. While this will work perfectly Dhall provides a cleaner solution for our \"injection problem\":+-- We can override the interpreter's @evaluateSettings@ with a custom set of+-- substitutions, like this: -- -- > {-# LANGUAGE OverloadedStrings #-} -- >@@ -2314,4 +2316,4 @@  -- $faq ----- <https://github.com/dhall-lang/dhall-lang/wiki/Frequently-Asked-Questions-(FAQ) Frequently Asked Questions (FAQ)>+-- <https://docs.dhall-lang.org/howtos/FAQ.html>
src/Dhall/TypeCheck.hs view
@@ -35,10 +35,9 @@ import Data.List.NonEmpty                (NonEmpty (..)) import Data.Monoid                       (Endo (..)) import Data.Semigroup                    (Max (..))-import Data.Sequence                     (Seq, ViewL (..))+import Data.Sequence                     (ViewL (..)) import Data.Set                          (Set) import Data.Text                         (Text)-import Data.Text.Prettyprint.Doc         (Doc, Pretty (..)) import Data.Typeable                     (Typeable) import Data.Void                         (Void, absurd) import Dhall.Context                     (Context)@@ -48,9 +47,10 @@     , Val (..)     , (~>)     )-import Dhall.Pretty                      (Ann)+import Dhall.Pretty                      (Ann, UnescapedLabel (..)) import Dhall.Src                         (Src)-import Lens.Family                       (over)+import Lens.Micro                        (anyOf, over)+import Prettyprinter                     (Doc, Pretty (..), vsep)  import Dhall.Syntax     ( Binding (..)@@ -61,28 +61,28 @@     , PreferAnnotation (..)     , RecordField (..)     , Var (..)+    , WithComponent (..)     ) -import qualified Data.Foldable                           as Foldable-import qualified Data.List.NonEmpty                      as NonEmpty+import qualified Data.Foldable               as Foldable+import qualified Data.Foldable.WithIndex     as Foldable.WithIndex+import qualified Data.List.NonEmpty          as NonEmpty import qualified Data.Map import qualified Data.Sequence import qualified Data.Set-import qualified Data.Text                               as Text-import qualified Data.Text.Prettyprint.Doc               as Pretty-import qualified Data.Text.Prettyprint.Doc.Render.String as Pretty+import qualified Data.Text                   as Text import qualified Data.Traversable import qualified Dhall.Context import qualified Dhall.Core import qualified Dhall.Diff-import qualified Dhall.Eval                              as Eval+import qualified Dhall.Eval                  as Eval import qualified Dhall.Map import qualified Dhall.Pretty import qualified Dhall.Pretty.Internal-import qualified Dhall.Set-import qualified Dhall.Syntax                            as Syntax+import qualified Dhall.Syntax                as Syntax import qualified Dhall.Util-import qualified Lens.Family+import qualified Prettyprinter               as Pretty+import qualified Prettyprinter.Render.String as Pretty  {-| A type synonym for `Void` @@ -93,9 +93,6 @@ type X = Void {-# DEPRECATED X "Use Data.Void.Void instead" #-} -traverseWithIndex_ :: Applicative f => (Int -> a -> f b) -> Seq a -> f ()-traverseWithIndex_ k xs = Foldable.sequenceA_ (Data.Sequence.mapWithIndex k xs)- axiom :: Const -> Either (TypeError s a) Const axiom Type = return Kind axiom Kind = return Sort@@ -189,7 +186,7 @@ {-| `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     no longer need to substitute `let` expressions at all (which is very@@ -229,7 +226,7 @@              go types n0 -        Lam (FunctionBinding { functionBindingVariable = x, functionBindingAnnotation = _A}) b -> do+        Lam _ (FunctionBinding { functionBindingVariable = x, functionBindingAnnotation = _A}) b -> do             tA' <- loop ctx _A              case tA' of@@ -252,7 +249,7 @@              return (VHPi x _A' (\u -> Eval.eval (Extend values x u) _B'')) -        Pi x _A _B -> do+        Pi _ x _A _B -> do             tA' <- loop ctx _A              kA <- case tA' of@@ -417,34 +414,26 @@              _R' <- loop ctx r -            tL' <- loop ctx (quote names _L')+            _ <- loop ctx (quote names _L')              let _L'' = quote names _L' -            case tL' of-                VConst Type ->-                    return ()-                _  -> do-                    let tL'' = quote names tL'-                    die (IfBranchMustBeTerm True l _L'' tL'')--            tR' <- loop ctx (quote names _R')+            _ <- loop ctx (quote names _R')              let _R'' = quote names _R' -            case tR' of-                VConst Type ->-                    return ()-                _ -> do-                    let tR'' = quote names tR'-                    die (IfBranchMustBeTerm True r _R'' tR'')-             if Eval.conv values _L' _R'                 then return ()                 else die (IfBranchMismatch l r _L'' _R'')              return _L' +        Bytes ->+            return (VConst Type)++        BytesLit _ ->+            return VBytes+         Natural ->             return (VConst Type) @@ -593,6 +582,33 @@         TextShow ->             return (VText ~> VText) +        Date ->+            return (VConst Type)++        DateLiteral _ ->+            return VDate++        DateShow ->+            return (VDate ~> VText)++        Time ->+            return (VConst Type)++        TimeLiteral _ _ ->+            return VTime++        TimeShow ->+            return (VTime ~> VText)++        TimeZone ->+            return (VConst Type)++        TimeZoneLiteral _ ->+            return VTimeZone++        TimeZoneShow ->+            return (VTimeZone ~> VText)+         List ->             return (VConst Type ~> VConst Type) @@ -627,7 +643,7 @@                                      Left (TypeError context t₁ err) -                    traverseWithIndex_ process ts₁+                    Foldable.WithIndex.itraverse_ process ts₁                      return (VList _T₀') @@ -782,14 +798,14 @@              Max c <- fmap Foldable.fold (Dhall.Map.unorderedTraverseWithKey process xTs)             return (VConst c)-        Combine mk l r -> do+        Combine _ mk l r -> do             _L' <- loop ctx l              let l'' = quote names (eval values l)              _R' <- loop ctx r -            let r'' = quote names (eval values l)+            let r'' = quote names (eval values r)              xLs' <- case _L' of                 VRecord xLs' ->@@ -831,7 +847,7 @@              combineTypes [] xLs' xRs' -        CombineTypes l r -> do+        CombineTypes _ l r -> do             _L' <- loop ctx l              let l' = eval values l@@ -878,7 +894,7 @@              return (VConst c) -        Prefer a l r -> do+        Prefer _ _ l r -> do             _L' <- loop ctx l              _R' <- loop ctx r@@ -891,11 +907,7 @@                      let l'' = quote names (eval values l) -                    case a of-                        PreferFromWith withExpression ->-                            die (MustUpdateARecord withExpression l'' _L'')-                        _ ->-                            die (MustCombineARecord '⫽' l'' _L'')+                    die (MustCombineARecord '⫽' l'' _L'')              xRs' <- case _R' of                 VRecord xRs' -> return xRs'@@ -913,13 +925,13 @@             _L' <- loop ctx l              case _L' of-                VRecord xLs' +                VRecord xLs'                   | not (Dhall.Map.member "default" xLs')                      -> die (InvalidRecordCompletion "default" l)                   | not (Dhall.Map.member "Type" xLs')                      -> die (InvalidRecordCompletion "Type" l)                   | otherwise-                     -> loop ctx (Annot (Prefer PreferFromCompletion (Field l def) r) (Field l typ))+                     -> loop ctx (Annot (Prefer mempty PreferFromCompletion (Field l def) r) (Field l typ))                 _ -> die (CompletionSchemaMustBeARecord l (quote names _L'))                where@@ -991,7 +1003,7 @@                                             n < 0                                          containsBadVar e =-                                            Lens.Family.anyOf+                                            anyOf                                                 Dhall.Core.subExpressions                                                 containsBadVar                                                 e@@ -1127,6 +1139,14 @@                         die (MapTypeMismatch (quote names (mapType _T')) _T₁'') +        ShowConstructor e -> do+            _E' <- loop ctx e+            case _E' of+              VUnion _ -> pure VText+              VOptional _ -> pure VText++              _ -> die ShowConstructorNotOnUnion+         Field e (Syntax.fieldSelectionLabel -> x) -> do             _E' <- loop ctx e @@ -1154,6 +1174,12 @@                              die (CantAccess text e'' _E'')         Project e (Left xs) -> do+            case duplicateElement xs of+                Just x -> do+                    die (DuplicateProjectionLabel x)+                Nothing -> do+                    return ()+             _E' <- loop ctx e              let _E'' = quote names _E'@@ -1167,7 +1193,7 @@                      let adapt = VRecord . Dhall.Map.unorderedFromList -                    fmap adapt (traverse process (Dhall.Set.toAscList xs))+                    fmap adapt (traverse process xs)                  _ -> do                     let text =@@ -1234,7 +1260,7 @@                 _ ->                     die (NotAnEquivalence _T) -        Equivalent x y -> do+        Equivalent _ x y -> do             _A₀' <- loop ctx x              let _A₀'' = quote names _A₀'@@ -1261,28 +1287,54 @@              return (VConst Type) -        With e ks v -> do-            tE' <- loop ctx e+        With e₀ ks₀ v₀ -> do+            tE₀' <- loop ctx e₀ -            kTs' <- case tE' of-                VRecord kTs' -> return kTs'-                _            -> die (NotWithARecord e (quote names tE'))+            -- The purpose of this inner loop is to ensure that we only need to+            -- typecheck the record once -            case ks of-                k :| [] -> do-                    tV' <- loop ctx v+            let with tE' ks v = case tE' of+                  VRecord kTs' ->+                    case ks of+                      WithLabel k :| [] -> do+                          tV' <- loop ctx v -                    return (VRecord (Dhall.Map.insert k tV' kTs'))-                k₀ :| k₁ : ks' -> do-                    let e₁ =-                            if Dhall.Map.member k₀ kTs'-                                then Field e (Syntax.makeFieldSelection k₀)-                                else RecordLit mempty+                          return (VRecord (Dhall.Map.insert k tV' kTs'))+                      WithLabel k₀ :| k₁ : ks' -> do+                          let _T =+                                  case Dhall.Map.lookup k₀ kTs' of+                                      Just _T' -> _T'+                                      Nothing  -> VRecord mempty -                    tV' <- loop ctx (With e₁ (k₁ :| ks') v)+                          tV' <- with _T (k₁ :| ks') v -                    return (VRecord (Dhall.Map.insert k₀ tV' kTs'))+                          return (VRecord (Dhall.Map.insert k₀ tV' kTs'))+                      WithQuestion :| _ -> do+                          die NotALabelPath +                  VOptional _O' -> do+                    case ks of++                        -- (Some x) with ? = v is valid iff the type of x is the same as the type of v.+                      WithQuestion :| [] -> do+                        tV' <- loop ctx v+                        if Eval.conv values _O' tV'+                          then return (VOptional _O')+                          else die OptionalWithTypeMismatch++                        -- (Some x) with ?.a.b = v is valid iff the type of x.a.b is the same as the type of v.+                      WithQuestion :| k₁ : ks' -> do+                        tV' <- with _O' (k₁ :| ks') v+                        if Eval.conv values _O' tV'+                          then return (VOptional _O')+                          else die OptionalWithTypeMismatch++                      WithLabel k :| _ -> die (NotAQuestionPath k)++                  _ -> die (NotWithARecord e₀ (quote names tE')) -- TODO: NotWithARecordOrOptional++            with tE₀' ks₀ v₀+         Note s e ->             case loop ctx e of                 Left (TypeError ctx' (Note s' e') m) ->@@ -1326,23 +1378,19 @@     | Untyped     | MissingListType     | MismatchedListElements Int (Expr s a) (Expr s a) (Expr s a)-    | InvalidListElement Int (Expr s a) (Expr s a) (Expr s a)     | InvalidListType (Expr s a)     | ListLitInvariant     | InvalidSome (Expr s a) (Expr s a) (Expr s a)     | InvalidPredicate (Expr s a) (Expr s a)     | IfBranchMismatch (Expr s a) (Expr s a) (Expr s a) (Expr s a)-    | IfBranchMustBeTerm Bool (Expr s a) (Expr s a) (Expr s a)     | InvalidFieldType Text (Expr s a)     | InvalidAlternativeType Text (Expr s a)     | ListAppendMismatch (Expr s a) (Expr s a)-    | MustUpdateARecord (Expr s a) (Expr s a) (Expr s a)     | MustCombineARecord Char (Expr s a) (Expr s a)     | InvalidDuplicateField Text (Expr s a) (Expr s a)     | InvalidRecordCompletion Text (Expr s a)     | CompletionSchemaMustBeARecord (Expr s a) (Expr s a)     | CombineTypesRequiresRecordType (Expr s a) (Expr s a)-    | RecordTypeMismatch Const Const (Expr s a) (Expr s a)     | DuplicateFieldCannotBeMerged (NonEmpty Text)     | FieldCollision (NonEmpty Text)     | FieldTypeCollision (NonEmpty Text)@@ -1359,12 +1407,12 @@     | HandlerInputTypeMismatch Text (Expr s a) (Expr s a)     | DisallowedHandlerType Text (Expr s a) (Expr s a) Text     | HandlerOutputTypeMismatch Text (Expr s a) Text (Expr s a)-    | InvalidHandlerOutputType Text (Expr s a) (Expr s a)     | MissingMergeType     | HandlerNotAFunction Text (Expr s a)     | CantAccess Text (Expr s a) (Expr s a)     | CantProject Text (Expr s a) (Expr s a)     | CantProjectByExpression (Expr s a)+    | DuplicateProjectionLabel Text     | MissingField Text (Expr s a)     | MissingConstructor Text (Expr s a)     | ProjectionTypeMismatch Text (Expr s a) (Expr s a) (Expr s a) (Expr s a)@@ -1382,17 +1430,26 @@     | CantListAppend (Expr s a) (Expr s a)     | CantAdd (Expr s a) (Expr s a)     | CantMultiply (Expr s a) (Expr s a)+    | OptionalWithTypeMismatch+    | NotALabelPath+    | NotAQuestionPath Text+    | ShowConstructorNotOnUnion     deriving (Show) +formatHints :: [Doc Ann] -> Doc Ann+formatHints hints = vsep (map format hints)+  where+    format hint = "\n\n\ESC[1;33mHint\ESC[0m: " <> hint+ shortTypeMessage :: (Eq a, Pretty a) => TypeMessage s a -> Doc Ann shortTypeMessage msg =-    "\ESC[1;31mError\ESC[0m: " <> short <> "\n"+    "\ESC[1;31mError\ESC[0m: " <> short <> formatHints hints <> "\n"   where     ErrorMessages {..} = prettyTypeMessage msg  longTypeMessage :: (Eq a, Pretty a) => TypeMessage s a -> Doc Ann longTypeMessage msg =-        "\ESC[1;31mError\ESC[0m: " <> short <> "\n"+        "\ESC[1;31mError\ESC[0m: " <> short <> formatHints hints <> "\n"     <>  "\n"     <>  long   where@@ -1404,6 +1461,8 @@ data ErrorMessages = ErrorMessages     { short :: Doc Ann     -- ^ Default succinct 1-line explanation of what went wrong+    , hints :: [Doc Ann]+    -- ^ Possibly-empty hints based on specific types involved in the error     , long  :: Doc Ann     -- ^ Longer and more detailed explanation of the error     }@@ -1414,6 +1473,12 @@ insert :: Pretty a => a -> Doc Ann insert = Dhall.Util.insert +emptyRecordTypeHint :: (Eq a, Pretty a) => Expr s a -> [Doc Ann]+emptyRecordTypeHint expr =+    if Eval.judgmentallyEqual expr (Record mempty) then+        ["{} is the empty record type, use {=} for the empty record value"]+    else []+ -- | Convert a `TypeMessage` to short- and long-form `ErrorMessages` prettyTypeMessage :: (Eq a, Pretty a) => TypeMessage s a -> ErrorMessages prettyTypeMessage (UnboundVariable x) = ErrorMessages {..}@@ -1422,6 +1487,8 @@   where     short = "Unbound variable: " <> Pretty.pretty x +    hints = []+     long =         "Explanation: Expressions can only reference previously introduced (i.e. “bound”)\n\         \variables that are still “in scope”                                             \n\@@ -1535,6 +1602,8 @@   where     short = "Invalid function input" +    hints = []+     long =         "Explanation: A function can accept an input “term” that has a given “type”, like\n\         \this:                                                                           \n\@@ -1604,6 +1673,8 @@   where     short = "Invalid function output" +    hints = []+     long =         "Explanation: A function can return an output “term” that has a given “type”,    \n\         \like this:                                                                      \n\@@ -1683,6 +1754,8 @@   where     short = "Not a function" +    hints = []+     long =         "Explanation: Expressions separated by whitespace denote function application,   \n\         \like this:                                                                      \n\@@ -1823,6 +1896,8 @@         <>  "\n"         <>  Dhall.Diff.doc (Dhall.Diff.diffNormalized expr1 expr3) +    hints = emptyRecordTypeHint expr2+     long =         "Explanation: Every function declares what type or kind of argument to accept    \n\         \                                                                                \n\@@ -1956,6 +2031,9 @@     short = "Expression doesn't match annotation\n"         <>  "\n"         <>  Dhall.Diff.doc (Dhall.Diff.diffNormalized expr1 expr2)++    hints = []+     long =         "Explanation: You can annotate an expression with its type or kind using the     \n\         \❰:❱ symbol, like this:                                                          \n\@@ -2052,6 +2130,8 @@   where     short = "❰Sort❱ has no type, kind, or sort" +    hints = []+     long =         "Explanation: There are five levels of expressions that form a hierarchy:        \n\         \                                                                                \n\@@ -2090,6 +2170,8 @@         <>  "\n"         <>  Dhall.Diff.doc (Dhall.Diff.diffNormalized Bool expr1) +    hints = []+     long =         "Explanation: Every ❰if❱ expression begins with a predicate which must have type \n\         \❰Bool❱                                                                          \n\@@ -2148,93 +2230,6 @@         txt0 = insert expr0         txt1 = insert expr1 -prettyTypeMessage (IfBranchMustBeTerm b expr0 expr1 expr2) =-    ErrorMessages {..}-  where-    short = "❰if❱ branch is not a term"--    long =-        "Explanation: Every ❰if❱ expression has a ❰then❱ and ❰else❱ branch, each of which\n\-        \is an expression:                                                               \n\-        \                                                                                \n\-        \                                                                                \n\-        \                   Expression for ❰then❱ branch                                 \n\-        \                   ⇩                                                            \n\-        \    ┌────────────────────────────────┐                                          \n\-        \    │ if True then \"Hello, world!\"   │                                        \n\-        \    │         else \"Goodbye, world!\" │                                        \n\-        \    └────────────────────────────────┘                                          \n\-        \                   ⇧                                                            \n\-        \                   Expression for ❰else❱ branch                                 \n\-        \                                                                                \n\-        \                                                                                \n\-        \These expressions must be a “term”, where a “term” is defined as an expression  \n\-        \that has a type thas has kind ❰Type❱                                            \n\-        \                                                                                \n\-        \For example, the following expressions are all valid “terms”:                   \n\-        \                                                                                \n\-        \                                                                                \n\-        \    ┌────────────────────┐                                                      \n\-        \    │ 1 : Natural : Type │  ❰1❱ is a term with a type (❰Natural❱) of kind ❰Type❱\n\-        \    └────────────────────┘                                                      \n\-        \      ⇧                                                                         \n\-        \      term                                                                      \n\-        \                                                                                \n\-        \                                                                                \n\-        \    ┌─────────────────────────────────────┐                                     \n\-        \    │ Natural/odd : Natural → Bool : Type │  ❰Natural/odd❱ is a term with a type\n\-        \    └─────────────────────────────────────┘  (❰Natural → Bool❱) of kind ❰Type❱  \n\-        \      ⇧                                                                         \n\-        \      term                                                                      \n\-        \                                                                                \n\-        \                                                                                \n\-        \However, the following expressions are " <> _NOT <> " valid terms:              \n\-        \                                                                                \n\-        \                                                                                \n\-        \    ┌────────────────────┐                                                      \n\-        \    │ Text : Type : Kind │  ❰Text❱ has kind (❰Type❱) of sort ❰Kind❱ and is      \n\-        \    └────────────────────┘  therefore not a term                                \n\-        \      ⇧                                                                         \n\-        \      type                                                                      \n\-        \                                                                                \n\-        \                                                                                \n\-        \    ┌───────────────────────────┐                                               \n\-        \    │ List : Type → Type : Kind │  ❰List❱ has kind (❰Type → Type❱) of sort      \n\-        \    └───────────────────────────┘  ❰Kind❱ and is therefore not a term           \n\-        \      ⇧                                                                         \n\-        \      type-level function                                                       \n\-        \                                                                                \n\-        \                                                                                \n\-        \This means that you cannot define an ❰if❱ expression that returns a type.  For  \n\-        \example, the following ❰if❱ expression is " <> _NOT <> " valid:                 \n\-        \                                                                                \n\-        \                                                                                \n\-        \    ┌─────────────────────────────┐                                             \n\-        \    │ if True then Text else Bool │  Invalid ❰if❱ expression                    \n\-        \    └─────────────────────────────┘                                             \n\-        \                   ⇧         ⇧                                                  \n\-        \                   type      type                                               \n\-        \                                                                                \n\-        \                                                                                \n\-        \Your ❰" <> txt0 <> "❱ branch of your ❰if❱ expression is:                        \n\-        \                                                                                \n\-        \" <> txt1 <> "\n\-        \                                                                                \n\-        \... which has kind:                                                             \n\-        \                                                                                \n\-        \" <> txt2 <> "\n\-        \                                                                                \n\-        \... of sort:                                                                    \n\-        \                                                                                \n\-        \" <> txt3 <> "\n\-        \                                                                                \n\-        \... and is not a term.  Therefore your ❰if❱ expression is not valid             \n"-      where-        txt0 = if b then "then" else "else"-        txt1 = insert expr0-        txt2 = insert expr1-        txt3 = insert expr2- prettyTypeMessage (IfBranchMismatch expr0 expr1 expr2 expr3) =     ErrorMessages {..}   where@@ -2242,6 +2237,8 @@         <>  "\n"         <>  Dhall.Diff.doc (Dhall.Diff.diffNormalized expr1 expr3) +    hints = []+     long =         "Explanation: Every ❰if❱ expression has a ❰then❱ and ❰else❱ branch, each of which\n\         \is an expression:                                                               \n\@@ -2316,6 +2313,8 @@   where     short = "Internal error: A non-empty list literal violated an internal invariant" +    hints = []+     long =         "Explanation: Internal error: A non-empty list literal violated an internal      \n\         \invariant.                                                                      \n\@@ -2331,6 +2330,8 @@   where     short = "Invalid type for ❰List❱" +    hints = []+     long =         "Explanation: ❰List❱s can optionally document their type with a type annotation, \n\         \like this:                                                                      \n\@@ -2393,6 +2394,8 @@   where     short = "An empty list requires a type annotation" +    hints = []+     long =         "Explanation: Lists do not require a type annotation if they have at least one   \n\         \element:                                                                        \n\@@ -2420,6 +2423,8 @@         <>  "\n"         <>  Dhall.Diff.doc (Dhall.Diff.diffNormalized expr0 expr2) +    hints = []+     long =         "Explanation: Every element in a list must have the same type                    \n\         \                                                                                \n\@@ -2451,49 +2456,12 @@         txt1 = pretty i         txt3 = insert expr2 -prettyTypeMessage (InvalidListElement i expr0 _expr1 expr2) =-    ErrorMessages {..}-  where-    short = "List element has the wrong type\n"-        <>  "\n"-        <>  Dhall.Diff.doc (Dhall.Diff.diffNormalized expr0 expr2)--    long =-        "Explanation: Every element in the list must have a type matching the type       \n\-        \annotation at the end of the list                                               \n\-        \                                                                                \n\-        \For example, this is a valid ❰List❱:                                            \n\-        \                                                                                \n\-        \                                                                                \n\-        \    ┌──────────────────────────┐                                                \n\-        \    │ [1, 2, 3] : List Natural │  Every element in this ❰List❱ is an ❰Natural❱  \n\-        \    └──────────────────────────┘                                                \n\-        \                                                                                \n\-        \                                                                                \n\-        \.. but this is " <> _NOT <> " a valid ❰List❱:                                   \n\-        \                                                                                \n\-        \                                                                                \n\-        \    ┌──────────────────────────────┐                                            \n\-        \    │ [1, \"ABC\", 3] : List Natural │  The second element is not an ❰Natural❱  \n\-        \    └──────────────────────────────┘                                            \n\-        \                                                                                \n\-        \                                                                                \n\-        \Your ❰List❱ elements should have this type:                                     \n\-        \                                                                                \n\-        \" <> txt0 <> "\n\-        \                                                                                \n\-        \... but the element at index #" <> txt1 <> " has this type instead:             \n\-        \                                                                                \n\-        \" <> txt3 <> "\n"-      where-        txt0 = insert expr0-        txt1 = pretty i-        txt3 = insert expr2- prettyTypeMessage (InvalidSome expr0 expr1 expr2) = ErrorMessages {..}   where     short = "❰Some❱ argument has the wrong type" +    hints = []+     long =         "Explanation: The ❰Some❱ constructor expects an argument that is a term, where   \n\         \the type of the type of a term must be ❰Type❱                                   \n\@@ -2536,6 +2504,8 @@   where     short = "Invalid field type" +    hints = []+     long =         "Explanation: Every record type annotates each field with a ❰Type❱, a ❰Kind❱, or \n\         \a ❰Sort❱ like this:                                                             \n\@@ -2579,6 +2549,8 @@   where     short = "Invalid alternative type" +    hints = []+     long =         "Explanation: Every union type specifies the type of each alternative, like this:\n\         \                                                                                \n\@@ -2636,6 +2608,8 @@         <>  "\n"         <>  Dhall.Diff.doc (Dhall.Diff.diffNormalized expr0 expr1) +    hints = []+     long =         "Explanation: You can append two ❰List❱s using the ❰#❱ operator, like this:      \n\         \                                                                                \n\@@ -2673,11 +2647,13 @@         txt0 = insert expr0         txt1 = insert expr1 -prettyTypeMessage (CompletionSchemaMustBeARecord expr0 expr1) = ErrorMessages {..} - where-   short = "The completion schema must be a record" +prettyTypeMessage (CompletionSchemaMustBeARecord expr0 expr1) = ErrorMessages {..}+  where+    short = "The completion schema must be a record" -   long = +    hints = []++    long =         "Explanation: You can complete records using the ❰::❱ operator:                  \n\         \                                                                                \n\         \    ┌─────────────────────────────────────────────────────────────────────────┐ \n\@@ -2697,11 +2673,13 @@         txt0 = insert expr0         txt1 = insert expr1 -prettyTypeMessage (InvalidRecordCompletion fieldName expr0) = ErrorMessages {..} - where-   short = "Completion schema is missing a field: " <> pretty fieldName+prettyTypeMessage (InvalidRecordCompletion fieldName expr0) = ErrorMessages {..}+  where+    short = "Completion schema is missing a field: " <> pretty fieldName -   long = +    hints = []++    long =         "Explanation: You can complete records using the ❰::❱ operator like this:\n\         \                                                                                \n\         \    ┌─────────────────────────────────────────────────────────────────────────┐ \n\@@ -2722,55 +2700,6 @@         txt0 = insert expr0         txt1 = pretty fieldName -prettyTypeMessage (MustUpdateARecord withExpression expression typeExpression) =-    ErrorMessages {..}-  where-    short = "You can only update records"--    long =-        "Explanation: You can update records using the ❰with❱ keyword, like this:        \n\-        \                                                                                \n\-        \                                                                                \n\-        \    ┌────────────────────────────────┐                                          \n\-        \    │ { x = { y = 1 } } with x.y = 2 │                                          \n\-        \    └────────────────────────────────┘                                          \n\-        \                                                                                \n\-        \                                                                                \n\-        \    ┌────────────────────────────────────────────────────────────┐              \n\-        \    │ λ(r : { foo : { bar : Bool } }) → r with foo.bar = False } │              \n\-        \    └────────────────────────────────────────────────────────────┘              \n\-        \                                                                                \n\-        \                                                                                \n\-        \... but you cannot update values that are not records.                          \n\-        \                                                                                \n\-        \For example, the following expression is " <> _NOT <> " valid:                  \n\-        \                                                                                \n\-        \                                                                                \n\-        \    ┌─────────────────┐                                                         \n\-        \    │ 1 with x = True │                                                         \n\-        \    └─────────────────┘                                                         \n\-        \      ⇧                                                                         \n\-        \      Invalid: Not a record                                                     \n\-        \                                                                                \n\-        \                                                                                \n\-        \────────────────────────────────────────────────────────────────────────────────\n\-        \                                                                                \n\-        \The following expression is not permitted:                                      \n\-        \                                                                                \n\-        \" <> insert withExpression' <> "\n\-        \                                                                                \n\-        \... because the left argument to ❰with❱:                                        \n\-        \                                                                                \n\-        \" <> insert expression <> "\n\-        \                                                                                \n\-        \... is not a record, but is actually a:                                         \n\-        \                                                                                \n\-        \" <> insert typeExpression <> "\n"-      where-        withExpression' = case withExpression of-            With record keys value -> With (Dhall.Core.normalize record) keys value-            _                      -> withExpression- prettyTypeMessage (MustCombineARecord c expression typeExpression) =     ErrorMessages {..}   where@@ -2780,6 +2709,8 @@      short = "You can only " <> action <> " records" +    hints = emptyRecordTypeHint expression+     long =         "Explanation: You can " <> action <> " records using the ❰" <> op <> "❱ operator, like this:\n\         \                                                                                \n\@@ -2837,6 +2768,8 @@   where     short = "Invalid duplicate field: " <> Dhall.Pretty.Internal.prettyLabel k +    hints = []+     long =         "Explanation: You can specify a field twice if both fields are themselves        \n\         \records, like this:                                                             \n\@@ -2894,7 +2827,7 @@         \                                                                                \n\         \... which is not a record type                                                  \n"       where-        txt0 = insert (Dhall.Pretty.Internal.escapeLabel True k)+        txt0 = insert (Dhall.Pretty.Internal.escapeLabel AnyLabelOrSome k)         txt1 = insert expr0         txt2 = insert expr1 @@ -2903,6 +2836,8 @@   where     short = "❰⩓❱ requires arguments that are record types" +    hints = []+     long =         "Explanation: You can only use the ❰⩓❱ operator on arguments that are record type\n\         \literals, like this:                                                            \n\@@ -2937,61 +2872,12 @@         txt0 = insert expr0         txt1 = insert expr1 -prettyTypeMessage (RecordTypeMismatch const0 const1 expr0 expr1) =-    ErrorMessages {..}-  where-    short = "Record type mismatch"--    long =-        "Explanation: You can only use the ❰⩓❱ operator on record types if they are both \n\-        \ ❰Type❱s or ❰Kind❱s:                                                            \n\-        \                                                                                \n\-        \                                                                                \n\-        \    ┌─────────────────────────────────────┐                                     \n\-        \    │ { age : Natural } ⩓ { name : Text } │  Valid: Both arguments are ❰Type❱s  \n\-        \    └─────────────────────────────────────┘                                     \n\-        \                                                                                \n\-        \                                                                                \n\-        \    ┌──────────────────────────────────────┐                                    \n\-        \    │ { Input : Type } ⩓ { Output : Type } │  Valid: Both arguments are ❰Kind❱s \n\-        \    └──────────────────────────────────────┘                                    \n\-        \                                                                                \n\-        \                                                                                \n\-        \... but you cannot combine a ❰Type❱ and a ❰Kind❱:                               \n\-        \                                                                                \n\-        \                                                                                \n\-        \    ┌────────────────────────────────────┐                                      \n\-        \    │ { Input : Type } ⩓ { name : Text } │  Invalid: The arguments do not match \n\-        \    └────────────────────────────────────┘                                      \n\-        \                                                                                \n\-        \                                                                                \n\-        \────────────────────────────────────────────────────────────────────────────────\n\-        \                                                                                \n\-        \You tried to combine the following record type:                                 \n\-        \                                                                                \n\-        \" <> txt0 <> "\n\-        \                                                                                \n\-        \... with this record types:                                                     \n\-        \                                                                                \n\-        \" <> txt1 <> "\n\-        \                                                                                \n\-        \... but the former record type is a:                                            \n\-        \                                                                                \n\-        \" <> txt2 <> "\n\-        \                                                                                \n\-        \... but the latter record type is a:                                            \n\-        \                                                                                \n\-        \" <> txt3 <> "\n"-      where-        txt0 = insert expr0-        txt1 = insert expr1-        txt2 = insert const0-        txt3 = insert const1- prettyTypeMessage (DuplicateFieldCannotBeMerged ks) = ErrorMessages {..}   where     short = "Duplicate field cannot be merged: " <> pretty (toPath ks) +    hints = []+     long =         "Explanation: Duplicate fields are only allowed if they are both records and if  \n\         \the two records can be recursively merged without collisions.                   \n\@@ -3046,7 +2932,7 @@         \                                                                                \n\         \" <> txt1 <> "\n"       where-        txt0 = insert (Dhall.Pretty.Internal.escapeLabel True (NonEmpty.head ks))+        txt0 = insert (Dhall.Pretty.Internal.escapeLabel AnyLabelOrSome (NonEmpty.head ks))          txt1 = insert (toPath ks) @@ -3054,6 +2940,8 @@   where     short = "Field collision on: " <> pretty (toPath ks) +    hints = []+     long =         "Explanation: You can recursively merge records using the ❰∧❱ operator:          \n\         \                                                                                \n\@@ -3118,6 +3006,8 @@   where     short = "Field type collision on: " <> pretty (toPath ks) +    hints = []+     long =         "Explanation: You can recursively merge record types using the ❰⩓❱ operator, like\n\         \this:                                                                           \n\@@ -3159,6 +3049,8 @@   where     short = "❰merge❱ expects a record of handlers" +    hints = []+     long =         "Explanation: You can ❰merge❱ the alternatives of a union or an ❰Optional❱ using \n\         \a record with one handler per alternative, like this:                           \n\@@ -3214,6 +3106,8 @@   where     short = "❰merge❱ expects a union or an ❰Optional❱" +    hints = []+     long =         "Explanation: You can ❰merge❱ the alternatives of a union or an ❰Optional❱ using \n\         \a record with one handler per alternative, like this:                           \n\@@ -3264,6 +3158,8 @@   where     short = "Unused handler" +    hints = []+     long =         "Explanation: You can ❰merge❱ the alternatives of a union or an ❰Optional❱ using \n\         \a record with one handler per alternative, like this:                           \n\@@ -3304,9 +3200,11 @@   where     short = case Data.Set.toList ks of          []       -> "Missing handler: " <> Dhall.Pretty.Internal.prettyLabel exemplar-         xs@(_:_) -> "Missing handlers: " <> (Pretty.hsep . Pretty.punctuate Pretty.comma +         xs@(_:_) -> "Missing handlers: " <> (Pretty.hsep . Pretty.punctuate Pretty.comma                                              . map Dhall.Pretty.Internal.prettyLabel $ exemplar:xs) +    hints = []+     long =         "Explanation: You can ❰merge❱ the alternatives of a union or an ❰Optional❱ using \n\         \a record with one handler per alternative, like this:                           \n\@@ -3348,6 +3246,8 @@   where     short = "An empty ❰merge❱ requires a type annotation" +    hints = []+     long =         "Explanation: A ❰merge❱ does not require a type annotation if the union has at   \n\         \least one alternative, like this                                                \n\@@ -3380,6 +3280,8 @@         <>  "\n"         <>  Dhall.Diff.doc (Dhall.Diff.diffNormalized expr1 expr2) +    hints = []+     long =         "Explanation: You can ❰merge❱ the alternatives of a union or an ❰Optional❱ using \n\         \a record with one handler per alternative, like this:                           \n\@@ -3440,6 +3342,8 @@   where     short = "Disallowed handler type" +    hints = []+     long =         "Explanation: You can ❰merge❱ the alternatives of a union or an ❰Optional❱ using \n\         \a record with one handler per alternative, like this:                           \n\@@ -3481,70 +3385,6 @@         \                                                                                \n\         \" <> insert variable <> "\n" -prettyTypeMessage (InvalidHandlerOutputType expr0 expr1 expr2) =-    ErrorMessages {..}-  where-    short = "Wrong handler output type\n"-        <>  "\n"-        <>  Dhall.Diff.doc (Dhall.Diff.diffNormalized expr1 expr2)--    long =-        "Explanation: You can ❰merge❱ the alternatives of a union or an ❰Optional❱ using \n\-        \a record with one handler per alternative, like this:                           \n\-        \                                                                                \n\-        \                                                                                \n\-        \    ┌─────────────────────────────────────────────────────────────────┐         \n\-        \    │ let union    = < Left : Natural | Right : Bool >.Left 2         │         \n\-        \    │ let handlers = { Left = Natural/even, Right = λ(x : Bool) → x } │         \n\-        \    │ in  merge handlers union : Bool                                 │         \n\-        \    └─────────────────────────────────────────────────────────────────┘         \n\-        \                                                                                \n\-        \                                                                                \n\-        \... as long as the output type of each handler function matches the declared    \n\-        \type of the result:                                                             \n\-        \                                                                                \n\-        \                                                                                \n\-        \    ┌───────────────────────────────────────────────────────────┐               \n\-        \    │ handlers : { Left : Natural → Bool, Right : Bool → Bool } │               \n\-        \    └───────────────────────────────────────────────────────────┘               \n\-        \                                    ⇧                    ⇧                      \n\-        \                                    These output types ...                      \n\-        \                                                                                \n\-        \                             ... must match the declared type of the ❰merge❱    \n\-        \                             ⇩                                                  \n\-        \    ┌─────────────────────────────┐                                             \n\-        \    │ merge handlers union : Bool │                                             \n\-        \    └─────────────────────────────┘                                             \n\-        \                                                                                \n\-        \                                                                                \n\-        \For example, the following expression is " <> _NOT <> " valid:                  \n\-        \                                                                                \n\-        \                                                                                \n\-        \    ┌──────────────────────────────────────────────────────────────────┐        \n\-        \    │ let union    = < Left : Natural | Right : Bool >.Left 2          │        \n\-        \    │ let handlers = { Left = Natural/even, Right = λ(x : Bool) → x }  │        \n\-        \    │ in  merge handlers union : Text                                  │        \n\-        \    └──────────────────────────────────────────────────────────────────┘        \n\-        \                                 ⇧                                              \n\-        \                                 Invalid: Doesn't match output of either handler\n\-        \                                                                                \n\-        \                                                                                \n\-        \Your handler for the following alternative:                                     \n\-        \                                                                                \n\-        \" <> txt0 <> "\n\-        \                                                                                \n\-        \... needs to return an output value of type:                                    \n\-        \                                                                                \n\-        \" <> txt1 <> "\n\-        \                                                                                \n\-        \... but actually returns an output value of a different type:                   \n\-        \                                                                                \n\-        \" <> txt2 <> "\n"-      where-        txt0 = insert expr0-        txt1 = insert expr1-        txt2 = insert expr2- prettyTypeMessage (HandlerOutputTypeMismatch key0 expr0 key1 expr1) =     ErrorMessages {..}   where@@ -3552,6 +3392,8 @@         <>  "\n"         <>  Dhall.Diff.doc (Dhall.Diff.diffNormalized expr0 expr1) +    hints = []+     long =         "Explanation: You can ❰merge❱ the alternatives of a union or an ❰Optional❱ using \n\         \a record with one handler per alternative, like this:                           \n\@@ -3606,6 +3448,8 @@   where     short = "Handler for "<> Dhall.Pretty.Internal.prettyLabel k <> " is not a function" +    hints = []+     long =         "Explanation: You can ❰merge❱ the alternatives of a union or an ❰Optional❱ using \n\         \a record with one handler per alternative, like this:                           \n\@@ -3643,10 +3487,12 @@         txt0 = insert k         txt1 = insert expr0 -prettyTypeMessage (MustMapARecord _expr0 _expr1) = ErrorMessages {..}+prettyTypeMessage (MustMapARecord provided _providedType) = ErrorMessages {..}   where     short = "❰toMap❱ expects a record value" +    hints = emptyRecordTypeHint provided+     long =         "Explanation: You can apply ❰toMap❱ to any homogenous record, like this:         \n\         \                                                                                \n\@@ -3675,6 +3521,8 @@   where     short = "❰toMap❱ expects a record of kind ❰Type❱" +    hints = []+     long =         "Explanation: You can apply ❰toMap❱ to any homogenous record of kind ❰Type❱, like\n\         \ this:                                                                          \n\@@ -3701,6 +3549,8 @@   where     short = "❰toMap❱ expects a homogenous record" +    hints = []+     long =         "Explanation: You can apply ❰toMap❱ to any homogenous record, like this:         \n\         \                                                                                \n\@@ -3728,6 +3578,8 @@         <>  "\n"         <>  Dhall.Diff.doc (Dhall.Diff.diffNormalized expr0 expr1) +    hints = []+     long =         "Explanation: a ❰toMap❱ application has been annotated with a type that doesn't  \n\         \match its inferred type.                                                        \n"@@ -3739,6 +3591,8 @@         <>  "\n"         <>  insert expr +    hints = []+     long =         "Explanation: A ❰toMap❱ applied to an empty record must have a type annotation:  \n\         \that matches a list of key-value pairs, like this                               \n\@@ -3756,6 +3610,8 @@   where     short = "An empty ❰toMap❱ requires a type annotation" +    hints = []+     long =         "Explanation: A ❰toMap❱ does not require a type annotation if the record has at  \n\         \least one field, like this                                                      \n\@@ -3779,6 +3635,8 @@   where     short = "Not a record or a union" +    hints = []+     long =         "Explanation: You can only access fields on records or unions, like this:        \n\         \                                                                                \n\@@ -3837,6 +3695,8 @@   where     short = "Not a record" +    hints = []+     long =         "Explanation: You can only project fields on records, like this:                 \n\         \                                                                                \n\@@ -3898,6 +3758,8 @@   where     short = "Selector is not a record type" +    hints = []+     long =         "Explanation: You can project by an expression if that expression is a record    \n\         \type:                                                                           \n\@@ -3953,10 +3815,44 @@       where         txt = insert expr +prettyTypeMessage (DuplicateProjectionLabel k) = ErrorMessages {..}+  where+    short = "Duplicate projection label: " <> Dhall.Pretty.Internal.prettyLabel k++    hints = []++    long =+        "Explanation: You can only specify a label once when projecting a record's fields\n\+        \by label.  For example, this is valid:                                          \n\+        \                                                                                \n\+        \                                                                                \n\+        \    ┌─────────────────────────────────────────┐                                 \n\+        \    │ { x = 1.1, y = 2.4, z = -0.3 }.{ x, y } │                                 \n\+        \    └─────────────────────────────────────────┘                                 \n\+        \                                                                                \n\+        \                                                                                \n\+        \... but this is not valid:                                                      \n\+        \                                                                                \n\+        \                                                                                \n\+        \    ┌─────────────────────────────────────────┐                                 \n\+        \    │ { x = 1.1, y = 2.4, z = -0.3 }.{ y, y } │                                 \n\+        \    └─────────────────────────────────────────┘                                 \n\+        \                                          ⇧                                     \n\+        \                                          Invalid: the label ❰y❱ appears twice  \n\+        \                                                                                \n\+        \                                                                                \n\+        \You tried to project the following field twice:                                 \n\+        \                                                                                \n\+        \" <> txt0 <> "\n"+      where+        txt0 = insert k+ prettyTypeMessage (MissingField k expr0) = ErrorMessages {..}   where     short = "Missing record field: " <> Dhall.Pretty.Internal.prettyLabel k +    hints = []+     long =         "Explanation: You can only access fields on records, like this:                  \n\         \                                                                                \n\@@ -3999,6 +3895,8 @@   where     short = "Missing constructor: " <> Dhall.Pretty.Internal.prettyLabel k +    hints = []+     long =         "Explanation: You can access constructors from unions, like this:                \n\         \                                                                                \n\@@ -4039,6 +3937,8 @@         <>  "\n"         <>  Dhall.Diff.doc (Dhall.Diff.diffNormalized expr2 expr3) +    hints = []+     long =         "Explanation: You can project a subset of fields from a record by specifying the \n\         \desired type of the final record, like this:                                    \n\@@ -4086,6 +3986,8 @@         <>  "\n"         <>  Dhall.Diff.doc (Dhall.Diff.diffNormalized expr0 expr1) +    hints = []+     long =         "Explanation: You can assert at type-checking time that two terms are equal if   \n\         \they have the same normal form, like this:                                      \n\@@ -4149,6 +4051,8 @@   where     short = "Not an equivalence\n" +    hints = []+     long =         "Explanation: The type annotation for an ❰assert❱ must evaluate to an equivalence\n\         \of the form ❰x ≡ y❱, like this:                                                 \n\@@ -4202,6 +4106,8 @@   where     short = "Incomparable expression\n" +    hints = []+     long =         "Explanation: You can use an ❰assert❱ to compare two terms for equivalence, like \n\         \this:                                                                           \n\@@ -4233,6 +4139,8 @@   where     short = "The two sides of the equivalence have different types" +    hints = []+     long =         "Explanation: You can use ❰≡❱ to compare two terms of the same type for          \n\         \equivalence, like this:                                                         \n\@@ -4272,6 +4180,8 @@   where     short = "❰with❱ only works on records" +    hints = []+     long =         "Explanation: You can use ❰with❱ to update a record, like this:                  \n\         \                                                                                \n\@@ -4323,6 +4233,8 @@   where     short = "You can only interpolate ❰Text❱" +    hints = []+     long =         "Explanation: Text interpolation only works on expressions of type ❰Text❱        \n\         \                                                                                \n\@@ -4385,6 +4297,8 @@   where     short = "❰++❱ only works on ❰Text❱" +    hints = []+     long =         "Explanation: The ❰++❱ operator expects two arguments that have type ❰Text❱      \n\         \                                                                                \n\@@ -4431,6 +4345,8 @@   where     short = "❰#❱ only works on ❰List❱s" +    hints = []+     long =         "Explanation: The ❰#❱ operator expects two arguments that are both ❰List❱s       \n\         \                                                                                \n\@@ -4461,11 +4377,133 @@ prettyTypeMessage (CantMultiply expr0 expr1) =         buildNaturalOperator "*" expr0 expr1 +prettyTypeMessage OptionalWithTypeMismatch = ErrorMessages {..}+  where+    short = "❰with❱ cannot change the type of an ❰Optional❱ value"+    hints = []+    long =+        "Explanation: The ❰with❱ keyword cannot change the type of a value stored inside \n\+        \of a ❰Some❱ constructor                                                         \n\+        \                                                                                \n\+        \For example, this is a valid use of ❰with❱:                                     \n\+        \                                                                                \n\+        \                                                                                \n\+        \           The old value has type ❰Natural❱                                     \n\+        \           ⇩                                                                    \n\+        \    ┌───────────────────┐                                                       \n\+        \    │ Some 1 with ? = 2 │                                                       \n\+        \    └───────────────────┘                                                       \n\+        \                      ⇧                                                         \n\+        \                      ... which matches the type of the new value, which is also\n\+        \                      ❰Natural❱                                                 \n\+        \                                                                                \n\+        \                                                                                \n\+        \... but the following example is not valid:                                     \n\+        \                                                                                \n\+        \                                                                                \n\+        \           The old value has type ❰Natural❱                                     \n\+        \           ⇩                                                                    \n\+        \    ┌──────────────────────┐                                                    \n\+        \    │ Some 1 with ? = True │                                                    \n\+        \    └──────────────────────┘                                                    \n\+        \                      ⇧                                                         \n\+        \                      ... but the new value has type ❰Bool❱, which does not     \n\+        \                      match                                                     \n"++prettyTypeMessage NotALabelPath = ErrorMessages {..}+  where+    short = "Use a label to update a record"+    hints = []+    long =+        "Explanation: The ❰with❱ keyword supports updating records by naming the field(s)\n\+        \to update, but you provided a path component of ❰?❱, which only works on        \n\+        \❰Optional❱ values and not records.                                              \n\+        \                                                                                \n\+        \For example, these are valid uses of ❰with❱ to update a record:                 \n\+        \                                                                                \n\+        \                                                                                \n\+        \    ┌──────────────────────┐                                                    \n\+        \    │ { x = 1 } with x = 2 │                                                    \n\+        \    └──────────────────────┘                                                    \n\+        \                                                                                \n\+        \                                                                                \n\+        \    ┌────────────────────────────────┐                                          \n\+        \    │ { x = { y = 1 } } with x.y = 2 │                                          \n\+        \    └────────────────────────────────┘                                          \n\+        \                                                                                \n\+        \                                                                                \n\+        \... but the following example is not valid:                                     \n\+        \                                                                                \n\+        \                                                                                \n\+        \    ┌──────────────────────┐                                                    \n\+        \    │ { x = 1 } with ? = 2 │                                                    \n\+        \    └──────────────────────┘                                                    \n\+        \                     ⇧                                                          \n\+        \                     This path component is reserved for updating ❰Optional❱    \n\+        \                     values and not records                                     \n\+        \                                                                                \n\+        \Note that you can update a field named ❰?❱ if you escape the path component,    \n\+        \though:                                                                         \n\+        \                                                                                \n\+        \                                                                                \n\+        \    ┌────────────────────────┐                                                  \n\+        \    │ { ? = 1 } with `?` = 2 │                                                  \n\+        \    └────────────────────────┘                                                  \n"++prettyTypeMessage (NotAQuestionPath k) = ErrorMessages {..}+  where+    short = "Use ❰?❱ to update an ❰Optional❱ value"+    hints = []+    long =+        "Explanation: The ❰with❱ keyword supports updating ❰Optional❱ values using a path\n\+        \component of ❰?❱, but you provided a path component other than ❰?❱.             \n\+        \                                                                                \n\+        \For example, these are valid uses of ❰with❱ to update an ❰Optional❱ value:      \n\+        \                                                                                \n\+        \                                                                                \n\+        \    ┌───────────────────┐                                                       \n\+        \    │ Some 1 with ? = 2 │                                                       \n\+        \    └───────────────────┘                                                       \n\+        \                                                                                \n\+        \                                                                                \n\+        \    ┌─────────────────────────────┐                                             \n\+        \    │ { x = Some 1 } with x.? = 2 │                                             \n\+        \    └─────────────────────────────┘                                             \n\+        \                                                                                \n\+        \                                                                                \n\+        \... but the following example is not valid:                                     \n\+        \                                                                                \n\+        \                                                                                \n\+        \    ┌──────────────────────┐                                                    \n\+        \    │ Some 1 with x = True │                                                    \n\+        \    └──────────────────────┘                                                    \n\+        \                  ⇧                                                             \n\+        \                  This path component should have been ❰?❱                      \n\+        \                                                                                \n\+        \                                                                                \n\+        \────────────────────────────────────────────────────────────────────────────────\n\+        \                                                                                \n\+        \You provided this path component:                                               \n\+        \                                                                                \n\+        \" <> txt0 <> "\n\+        \                                                                                \n\+        \... which perhaps should have been ❰?❱.                                         \n"+      where+        txt0 = insert k++prettyTypeMessage ShowConstructorNotOnUnion = ErrorMessages {..}+  where+      short = "ShowConstructorNotOnUnion"+      hints = []+      long = ""+ buildBooleanOperator :: Pretty a => Text -> Expr s a -> Expr s a -> ErrorMessages buildBooleanOperator operator expr0 expr1 = ErrorMessages {..}   where     short = "❰" <> txt2 <> "❱ only works on ❰Bool❱s" +    hints = []+     long =         "Explanation: The ❰" <> txt2 <> "❱ operator expects two arguments that have type ❰Bool❱\n\         \                                                                                \n\@@ -4495,6 +4533,8 @@   where     short = "❰" <> txt2 <> "❱ only works on ❰Natural❱s" +    hints = []+     long =         "Explanation: The ❰" <> txt2 <> "❱ operator expects two arguments that have type ❰Natural❱\n\         \                                                                                \n\@@ -4626,8 +4666,6 @@         pure MissingListType     MismatchedListElements a b c d ->         MismatchedListElements <$> pure a <*> f b <*> f c <*> f d-    InvalidListElement a b c d ->-        InvalidListElement <$> pure a <*> f b <*> f c <*> f d     InvalidListType a ->         InvalidListType <$> f a     ListLitInvariant ->@@ -4638,8 +4676,6 @@         InvalidPredicate <$> f a <*> f b     IfBranchMismatch a b c d ->         IfBranchMismatch <$> f a <*> f b <*> f c <*> f d-    IfBranchMustBeTerm a b c d ->-        IfBranchMustBeTerm <$> pure a <*> f b <*> f c <*> f d     InvalidFieldType a b ->         InvalidFieldType <$> pure a <*> f b     InvalidAlternativeType a b ->@@ -4648,18 +4684,14 @@         ListAppendMismatch <$> f a <*> f b     InvalidDuplicateField a b c ->         InvalidDuplicateField a <$> f b <*> f c-    MustUpdateARecord a b c ->-        MustUpdateARecord <$> f a <*> f b <*> f c     MustCombineARecord a b c ->         MustCombineARecord <$> pure a <*> f b <*> f c-    InvalidRecordCompletion a l -> +    InvalidRecordCompletion a l ->         InvalidRecordCompletion a <$> f l-    CompletionSchemaMustBeARecord l r -> +    CompletionSchemaMustBeARecord l r ->         CompletionSchemaMustBeARecord <$> f l <*> f r     CombineTypesRequiresRecordType a b ->         CombineTypesRequiresRecordType <$> f a <*> f b-    RecordTypeMismatch a b c d ->-        RecordTypeMismatch <$> pure a <*> pure b <*> f c <*> f d     DuplicateFieldCannotBeMerged a ->         pure (DuplicateFieldCannotBeMerged a)     FieldCollision a ->@@ -4692,8 +4724,6 @@         DisallowedHandlerType <$> pure a <*> f b <*> f c <*> pure d     HandlerOutputTypeMismatch a b c d ->         HandlerOutputTypeMismatch <$> pure a <*> f b <*> pure c <*> f d-    InvalidHandlerOutputType a b c ->-        InvalidHandlerOutputType <$> pure a <*> f b <*> f c     MissingMergeType ->         pure MissingMergeType     HandlerNotAFunction a b ->@@ -4704,6 +4734,8 @@         CantProject <$> pure a <*> f b <*> f c     CantProjectByExpression a ->         CantProjectByExpression <$> f a+    DuplicateProjectionLabel a ->+        pure (DuplicateProjectionLabel a)     MissingField a b ->         MissingField <$> pure a <*> f b     MissingConstructor a b ->@@ -4738,6 +4770,14 @@         CantAdd <$> f a <*> f b     CantMultiply a b ->         CantMultiply <$> f a <*> f b+    OptionalWithTypeMismatch ->+        pure OptionalWithTypeMismatch+    NotALabelPath ->+        pure NotALabelPath+    NotAQuestionPath k ->+        pure (NotAQuestionPath k)+    ShowConstructorNotOnUnion ->+        pure ShowConstructorNotOnUnion  {-| Newtype used to wrap error messages so that they render with a more     detailed explanation of what went wrong@@ -4800,4 +4840,12 @@ toPath :: (Functor list, Foldable list) => list Text -> Text toPath ks =     Text.intercalate "."-        (Foldable.toList (fmap (Dhall.Pretty.Internal.escapeLabel True) ks))+        (Foldable.toList (fmap (Dhall.Pretty.Internal.escapeLabel AnyLabelOrSome) ks))++duplicateElement :: Ord a => [a] -> Maybe a+duplicateElement = go Data.Set.empty+  where+    go _ [] = Nothing+    go found (x : xs)+        | Data.Set.member x found = Just x+        | otherwise               = go (Data.Set.insert x found) xs
src/Dhall/URL.hs view
@@ -3,14 +3,12 @@  module Dhall.URL where -import Data.Text   (Text)+import Data.Text (Text)  import Dhall.Syntax (Directory (..), File (..), Scheme (..), URL (..)) -import qualified Network.URI.Encode as URI.Encode- renderComponent :: Text -> Text-renderComponent component = "/" <> URI.Encode.encodeText component+renderComponent component = "/" <> component  renderQuery :: Text -> Text renderQuery query = "?" <> query
src/Dhall/Util.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE NamedFieldPuns    #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards   #-} @@ -8,9 +9,10 @@     , snipDoc     , insert     , _ERROR+    , _WARNING+    , printWarning     , Censor(..)     , Input(..)-    , PossiblyTransitiveInput(..)     , Transitivity(..)     , OutputMode(..)     , Output(..)@@ -19,26 +21,35 @@     , getExpressionAndHeaderFromStdinText     , Header(..)     , CheckFailed(..)+    , MultipleCheckFailed(..)+    , handleMultipleChecksFailed+    , renderExpression     ) where -import Control.Exception         (Exception (..))-import Control.Monad.IO.Class    (MonadIO (..))-import Data.Bifunctor            (first)-import Data.String               (IsString)-import Data.Text                 (Text)-import Data.Text.Prettyprint.Doc (Doc, Pretty)-import Dhall.Parser              (Header (..), ParseError)-import Dhall.Pretty              (Ann)-import Dhall.Src                 (Src)-import Dhall.Syntax              (Expr, Import)+import Control.Exception      (Exception (..))+import Control.Monad.IO.Class (MonadIO (..))+import Data.Bifunctor         (first)+import Data.Either            (lefts)+import Data.Foldable          (toList)+import Data.List.NonEmpty     (NonEmpty (..))+import Data.String            (IsString)+import Data.Text              (Text)+import Dhall.Parser           (Header (..), ParseError)+import Dhall.Pretty           (Ann, CharacterSet)+import Dhall.Src              (Src)+import Dhall.Syntax           (Expr, Import)+import Prettyprinter          (Doc, Pretty)  import qualified Control.Exception import qualified Data.Text import qualified Data.Text.IO-import qualified Data.Text.Prettyprint.Doc                 as Pretty-import qualified Data.Text.Prettyprint.Doc.Render.Terminal as Pretty.Terminal import qualified Dhall.Parser import qualified Dhall.Pretty+import qualified Prettyprinter                 as Pretty+import qualified Prettyprinter.Render.Terminal as Pretty.Terminal+import qualified Prettyprinter.Render.Text     as Pretty.Text+import qualified System.Console.ANSI           as ANSI+import qualified System.IO                     as IO  -- | Utility function to cut out the interior of a large text block snip :: Text -> Text@@ -102,6 +113,21 @@ _ERROR :: IsString string => string _ERROR = "\ESC[1;31mError\ESC[0m" +-- | Prefix used for error messages+_WARNING :: IsString string => string+_WARNING = "\ESC[1;33mWarning\ESC[0m"++-- | Output a warning message on stderr.+printWarning :: (MonadIO m) => String -> m ()+printWarning message = do+    let warning =+                "\n"+            <> _WARNING+            <> ": "+            <> message++    liftIO $ IO.hPutStrLn IO.stderr warning+ get     :: (String -> Text -> Either ParseError a)     -> Censor@@ -112,13 +138,13 @@         case input of             Input_ (InputFile file) -> Data.Text.IO.readFile file             Input_ StandardInput    -> Data.Text.IO.getContents-            StdinText text          -> pure text+            StdinText _ text        -> pure text      let name =             case input of                 Input_ (InputFile file) -> file                 Input_ StandardInput    -> "(input)"-                StdinText _             -> "(input)"+                StdinText inputName _   -> inputName      let result = parser name inText @@ -140,17 +166,14 @@ data Censor = NoCensor | Censor  -- | Path to input-data Input = StandardInput | InputFile FilePath+data Input = StandardInput | InputFile FilePath deriving (Eq)  -- | Path to input or raw input text, necessary since we can't read STDIN twice-data InputOrTextFromStdin = Input_ Input | StdinText Text--{-| For utilities that may want to process transitive dependencies, like-    @dhall freeze@--}-data PossiblyTransitiveInput-    = NonTransitiveStandardInput-    | PossiblyTransitiveInputFile FilePath Transitivity+data InputOrTextFromStdin+    = Input_ Input+    | StdinText String Text+    -- ^ @StdinText name text@ where name is a user-friendly name describing the+    -- input expression, used in parsing error messages  {-| Specifies whether or not an input's transitive dependencies should also be     processed.  Transitive dependencies are restricted to relative file imports.@@ -170,15 +193,25 @@ -} data OutputMode = Write | Check +-- | A check failure corresponding to a single input.+-- This type is intended to be used with 'MultipleCheckFailed' for error+-- reporting.+newtype CheckFailed = CheckFailed { input :: Input }+ -- | Exception thrown when the @--check@ flag to a command-line subcommand fails-data CheckFailed = CheckFailed { command :: Text, modified :: Text }+data MultipleCheckFailed = MultipleCheckFailed+  { command :: Text+  , modified :: Text+  , inputs :: NonEmpty Input+  } -instance Exception CheckFailed+instance Exception MultipleCheckFailed -instance Show CheckFailed where-    show CheckFailed{..} =-         _ERROR <> ": ❰dhall " <> command_ <> " --check❱ failed\n\-        \\n\+instance Show MultipleCheckFailed where+    show MultipleCheckFailed{..} =+         _ERROR <> ": ❰dhall " <> command_ <> " --check❱ failed on:\n\+        \\n" <> files <>+        "\n\         \You ran ❰dhall " <> command_ <> " --check❱, but the input appears to have not\n\         \been " <> modified_ <> " before, or was changed since the last time the input\n\         \was " <> modified_ <> ".\n"@@ -187,6 +220,32 @@          command_ = Data.Text.unpack command +        files = unlines . map format $ toList inputs++        format input = case input of+            StandardInput -> "↳ (stdin)"+            InputFile file -> "↳ " <> file++-- | Run IO for multiple inputs, then collate all the check failures before+-- throwing if there was any failure+handleMultipleChecksFailed+    :: (Foldable t, Traversable t)+    => Text+    -> Text+    -> (a -> IO (Either CheckFailed ()))+    -> t a+    -> IO ()+handleMultipleChecksFailed command modified f xs = post =<< mapM f xs+  where+    post results =+        case lefts (toList results) of+            [] -> pure ()+            cf:cfs -> Control.Exception.throwIO $ MultipleCheckFailed+                { command+                , modified+                , inputs = fmap input (cf:|cfs)+                }+ -- | Convenient utility for retrieving an expression getExpression :: Censor -> Input -> IO (Expr Src Import) getExpression censor = get Dhall.Parser.exprFromText censor . Input_@@ -199,6 +258,34 @@ -- | Convenient utility for retrieving an expression along with its header from -- | text already read from STDIN (so it's not re-read) getExpressionAndHeaderFromStdinText-    :: Censor -> Text -> IO (Header, Expr Src Import)-getExpressionAndHeaderFromStdinText censor =-    get Dhall.Parser.exprAndHeaderFromText censor . StdinText+    :: Censor -> String -> Text -> IO (Header, Expr Src Import)+getExpressionAndHeaderFromStdinText censor inputName =+    get Dhall.Parser.exprAndHeaderFromText censor . StdinText inputName++{-| Convenient utility to output an expression either to a file+    or to stdout.+-}+renderExpression :: Pretty a => CharacterSet -> Bool -> Maybe FilePath -> Expr Src a -> IO ()+renderExpression characterSet plain output expression = do+    let document = Dhall.Pretty.prettyCharacterSet characterSet expression++    let stream = Dhall.Pretty.layout document++    case output of+        Nothing -> do+            supportsANSI <- ANSI.hSupportsANSI IO.stdout++            let ansiStream =+                    if supportsANSI && not plain+                    then fmap Dhall.Pretty.annToAnsiStyle stream+                    else Pretty.unAnnotateS stream++            Pretty.Terminal.renderIO IO.stdout ansiStream++            Data.Text.IO.putStrLn ""++        Just file_ ->+            IO.withFile file_ IO.WriteMode $ \h -> do+                Pretty.Text.renderIO h stream++                Data.Text.IO.hPutStrLn h ""
tests/Dhall/Test/Dhall.hs view
@@ -13,21 +13,22 @@  module Dhall.Test.Dhall where -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 Control.Exception      (SomeException, throwIO, try)+import Data.Either.Validation (validationToEither)+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 @@ -43,7 +44,7 @@    = LitF Natural    | AddF expr expr    | MulF expr expr-   deriving (Eq, Functor, Generic, FromDhall, Show)+   deriving (Eq, Functor, Generic, FromDhall, ToDhall, Show)  instance Eq1 ExprF where     liftEq _  (LitF aL) (LitF aR) = aL == aR@@ -91,14 +92,15 @@   let expectedMsg =         "\ESC[1;31mError\ESC[0m: Invalid Dhall.Decoder                                               \n\         \                                                                                \n\-        \Every Decoder must provide an extract function that succeeds if an expression   \n\-        \matches the expected type.  You provided a Decoder that disobeys this contract  \n\+        \Every Decoder must provide an extract function that does not fail with a type   \n\+        \error if an expression matches the expected type.  You provided a Decoder that  \n\+        \disobeys this contract                                                          \n\         \                                                                                \n\         \The Decoder provided has the expected dhall type:                               \n\         \                                                                                \n\         \↳ { bar : Natural, foo : Text }\n\         \                                                                                \n\-        \and it couldn't extract a value from the well-typed expression:                 \n\+        \and it threw a type error during extraction from the well-typed expression:     \n\         \                                                                                \n\         \↳ { bar = 0, foo = \"foo\" }\n\         \                                                                                \n"@@ -141,6 +143,11 @@ shouldHaveWorkingRecursiveFromDhall = testGroup "recursive FromDhall instance"     [ testCase "works for a recursive expression" $ do         actual <- Dhall.input Dhall.auto "./tests/recursive/expr0.dhall"++        expected @=? actual+    , testCase "roundtrips (one-way)" $ do+        let expr = Dhall.embed Dhall.inject expected+        actual <- either throwIO pure . validationToEither . Dhall.extract Dhall.auto $ expr          expected @=? actual     , testCase "passes a shadowing sanity check" $ do
tests/Dhall/Test/Diff.hs view
@@ -2,21 +2,19 @@  module Dhall.Test.Diff where -import Data.Text   (Text)-import Prelude     hiding (FilePath)-import Test.Tasty  (TestTree)-import Turtle      (FilePath)+import Data.Text  (Text)+import Test.Tasty (TestTree) -import qualified Data.Text                             as Text-import qualified Data.Text.IO                          as Text.IO-import qualified Data.Text.Prettyprint.Doc.Render.Text as Pretty.Text-import qualified Dhall.Core                            as Core-import qualified Dhall.Diff                            as Diff-import qualified Dhall.Parser                          as Parser+import qualified Data.Text                 as Text+import qualified Data.Text.IO              as Text.IO+import qualified Dhall.Core                as Core+import qualified Dhall.Diff                as Diff+import qualified Dhall.Parser              as Parser import qualified Dhall.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 Dhall.Test.Util           as Test.Util+import qualified Prettyprinter.Render.Text as Pretty.Text+import qualified Test.Tasty                as Tasty+import qualified Test.Tasty.HUnit          as Tasty.HUnit import qualified Turtle  diffDirectory :: FilePath
+ tests/Dhall/Test/DirectoryTree.hs view
@@ -0,0 +1,149 @@+{-# LANGUAGE CPP               #-}+{-# LANGUAGE OverloadedLists   #-}+{-# LANGUAGE OverloadedStrings #-}++module Dhall.Test.DirectoryTree (tests) where++import Control.Monad+import Data.Either            (partitionEithers)+import Data.Either.Validation+import Dhall.DirectoryTree+import Lens.Micro             (set)+import System.FilePath        ((</>))+import Test.Tasty+import Test.Tasty.HUnit++import qualified Data.List+import qualified Data.Text.IO+import qualified Dhall+import qualified Dhall.Core+import qualified System.Directory         as Directory+import qualified System.FilePath          as FilePath+import qualified System.PosixCompat.Files as Files++tests :: TestTree+tests = testGroup "to-directory-tree"+    [ testGroup "fixpointed"+        [ fixpointedType+        , fixpointedEmpty+        , fixpointedSimple+        , fixpointedAllowPathSeparators+#ifndef mingw32_HOST_OS+        , fixpointedPermissions+        , fixpointedUserGroup+#endif+        ]+    ]++fixpointedType :: TestTree+fixpointedType = testCase "Type is as expected" $ do+    let file = "./tests/to-directory-tree/type.dhall"+    ref <- Dhall.inputExpr file+    expected' <- case directoryTreeType of+        Failure e -> assertFailure $ show e+        Success expr -> return expr+    assertBool "Type mismatch" $ expected' `Dhall.Core.judgmentallyEqual` ref++fixpointedEmpty :: TestTree+fixpointedEmpty = testCase "empty" $ do+    let outDir = "./tests/to-directory-tree/fixpoint-empty.out"+        path = "./tests/to-directory-tree/fixpoint-empty.dhall"+    entries <- runDirectoryTree False outDir path+    entries @?= [Directory outDir]++fixpointedSimple :: TestTree+fixpointedSimple = testCase "simple" $ do+    let outDir = "./tests/to-directory-tree/fixpoint-simple.out"+        path = "./tests/to-directory-tree/fixpoint-simple.dhall"+    entries <- runDirectoryTree False outDir path+    entries @?= Data.List.sort+        [ Directory outDir+        , File $ outDir </> "file"+        , Directory $ outDir </> "directory"+        ]++fixpointedAllowPathSeparators :: TestTree+fixpointedAllowPathSeparators = testCase "allow-path-separators" $ do+    let outDir = "./tests/to-directory-tree/fixpoint-allow-path-separators.out"+        path = "./tests/to-directory-tree/fixpoint-allow-path-separators.dhall"+    entries <- runDirectoryTree True outDir path+    entries @?= Data.List.sort+        [ Directory outDir+        , Directory $ outDir </> "non-existent-1"+        , File $ outDir </> "non-existent-1" </> "file"+        , Directory $ outDir </> "non-existent-2"+        , Directory $ outDir </> "non-existent-2" </> "directory"+        ]++{-+This test is disabled on Windows as it fails due to limitations of the :+    expected: 448+    but got: 438+-}+fixpointedPermissions :: TestTree+fixpointedPermissions = testCase "permissions" $ do+    let outDir = "./tests/to-directory-tree/fixpoint-permissions.out"+        path = "./tests/to-directory-tree/fixpoint-permissions.dhall"+    entries <- runDirectoryTree False outDir path+    entries @?=+        [ Directory outDir+        , File $ outDir </> "file"+        ]+    s <- Files.getFileStatus $ outDir </> "file"+    let mode = Files.fileMode s `Files.intersectFileModes` Files.accessModes+    prettyFileMode mode @?= prettyFileMode Files.ownerModes++fixpointedUserGroup :: TestTree+fixpointedUserGroup = testCase "user and group" $ do+    let file = "./tests/to-directory-tree/fixpoint-usergroup.dhall"+    expr <- Dhall.inputExpr file+    entries <- decodeDirectoryTree expr+    entries @?=+        [ TextFileEntry $ Entry+            { entryName = "ids"+            , entryContent = ""+            , entryUser = Just (UserId 0)+            , entryGroup = Just (GroupId 0)+            , entryMode = Nothing+            }+        , TextFileEntry $ Entry+            { entryName = "names"+            , entryContent = ""+            , entryUser = Just (UserName "user")+            , entryGroup = Just (GroupName "group")+            , entryMode = Nothing+            }+        ]++runDirectoryTree :: Bool -> FilePath -> FilePath -> IO [WalkEntry]+runDirectoryTree allowSeparators outDir path = do+    doesOutDirExist <- Directory.doesDirectoryExist outDir+    when doesOutDirExist $+        Directory.removeDirectoryRecursive outDir+    Directory.createDirectoryIfMissing True outDir++    text <- Data.Text.IO.readFile path+    let inputSettings+            = set Dhall.rootDirectory (FilePath.takeDirectory path)+            . set Dhall.sourceName path+            $ Dhall.defaultInputSettings+    expr <- Dhall.inputExprWithSettings inputSettings text++    toDirectoryTree allowSeparators outDir $ Dhall.Core.denote expr++    Data.List.sort <$> walkFsTree outDir++data WalkEntry+    = Directory FilePath+    | File FilePath+    deriving (Eq, Ord, Show)++walkFsTree :: FilePath -> IO [WalkEntry]+walkFsTree dir = do+    entries <- Directory.listDirectory dir+    (ds, fs) <- fmap partitionEithers $ forM entries $ \path -> do+        let path' = dir </> path+        isDirectory <- Directory.doesDirectoryExist path'+        return $ if isDirectory then Left path' else Right (File path')+    entries' <- traverse walkFsTree ds+    return $ Directory dir : fs <> concat entries'
tests/Dhall/Test/Format.hs view
@@ -7,17 +7,16 @@ import Dhall.Pretty (CharacterSet (..)) import Test.Tasty   (TestTree) -import qualified Control.Monad                         as Monad-import qualified Data.Text                             as Text-import qualified Data.Text.IO                          as Text.IO-import qualified Data.Text.Prettyprint.Doc             as Doc-import qualified Data.Text.Prettyprint.Doc.Render.Text as Doc.Render.Text-import qualified Dhall.Core                            as Core-import qualified Dhall.Parser                          as Parser-import qualified Dhall.Pretty                          as Pretty-import qualified Dhall.Test.Util                       as Test.Util-import qualified Test.Tasty                            as Tasty-import qualified Test.Tasty.Silver                     as Tasty.Silver+import qualified Data.Text                 as Text+import qualified Data.Text.IO              as Text.IO+import qualified Dhall.Core                as Core+import qualified Dhall.Parser              as Parser+import qualified Dhall.Pretty              as Pretty+import qualified Dhall.Test.Util           as Test.Util+import qualified Prettyprinter             as Doc+import qualified Prettyprinter.Render.Text as Doc.Render.Text+import qualified Test.Tasty                as Tasty+import qualified Test.Tasty.Silver         as Tasty.Silver import qualified Turtle  getTests :: IO TestTree@@ -27,7 +26,7 @@              let skip = [ "./tests/format/asciiA.dhall" ] -            Monad.guard (path `notElem` skip)+            path `Test.Util.pathNotIn` skip              return path 
tests/Dhall/Test/Freeze.hs view
@@ -4,9 +4,7 @@  import Data.Text    (Text) import Dhall.Freeze (Intent (..), Scope (..))-import Prelude      hiding (FilePath) import Test.Tasty   (TestTree)-import Turtle       (FilePath)  import qualified Data.Text        as Text import qualified Data.Text.IO     as Text.IO@@ -18,19 +16,30 @@ import qualified Test.Tasty.HUnit as Tasty.HUnit import qualified Turtle -freezeDirectory :: FilePath-freezeDirectory = "./tests/freeze"+freezeDirectoryCached :: FilePath+freezeDirectoryCached = "./tests/freeze/cached" +freezeDirectorySecure :: FilePath+freezeDirectorySecure = "./tests/freeze/secure"+ getTests :: IO TestTree getTests = do-    freezeTests <- Test.Util.discover (Turtle.chars <* "A.dhall") freezeTest (Turtle.lstree freezeDirectory)+    freezeCachedTests <- Test.Util.discover (Turtle.chars <* "A.dhall")+        (freezeTest freezeDirectoryCached Cache)+        (Turtle.lstree freezeDirectoryCached)+    freezeSecureTests <- Test.Util.discover (Turtle.chars <* "A.dhall")+        (freezeTest freezeDirectorySecure Secure)+        (Turtle.lstree freezeDirectorySecure) -    let testTree = Tasty.testGroup "freeze tests" [ freezeTests ]+    let testTree = Tasty.testGroup "freeze tests"+            [ Tasty.testGroup "cached" [freezeCachedTests]+            , Tasty.testGroup "secure" [freezeSecureTests]+            ]      return testTree -freezeTest :: Text -> TestTree-freezeTest prefix =+freezeTest :: FilePath -> Intent -> Text -> TestTree+freezeTest dir intent prefix =     Tasty.HUnit.testCase (Text.unpack prefix) $ do         let inputFile  = Text.unpack (prefix <> "A.dhall")         let outputFile = Text.unpack (prefix <> "B.dhall")@@ -39,7 +48,7 @@          parsedInput <- Core.throws (Parser.exprFromText mempty inputText) -        actualExpression <- Freeze.freezeExpression (Turtle.encodeString freezeDirectory) AllImports Cache parsedInput+        actualExpression <- Freeze.freezeExpression dir AllImports intent parsedInput          let actualText = Core.pretty actualExpression <> "\n" 
tests/Dhall/Test/Import.hs view
@@ -1,17 +1,16 @@+{-# LANGUAGE CPP               #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeApplications  #-}  module Dhall.Test.Import where  import Control.Exception (SomeException) import Data.Text         (Text)-import Dhall.Import      (MissingImports (..))-import Dhall.Parser      (SourcedException (..))-import Prelude           hiding (FilePath)+import Data.Void         (Void)+import System.FilePath   ((</>)) import Test.Tasty        (TestTree)-import Turtle            (FilePath, (</>))  import qualified Control.Exception                as Exception-import qualified Control.Monad                    as Monad import qualified Control.Monad.Trans.State.Strict as State import qualified Data.Text                        as Text import qualified Data.Text.IO                     as Text.IO@@ -19,13 +18,18 @@ import qualified Dhall.Import                     as Import import qualified Dhall.Parser                     as Parser import qualified Dhall.Test.Util                  as Test.Util-import qualified Network.HTTP.Client              as HTTP-import qualified Network.HTTP.Client.TLS          as HTTP import qualified System.FilePath                  as FilePath+import qualified System.IO.Temp                   as Temp import qualified Test.Tasty                       as Tasty import qualified Test.Tasty.HUnit                 as Tasty.HUnit import qualified Turtle +#if defined(WITH_HTTP) && defined(NETWORK_TESTS)+import qualified Network.HTTP.Client     as HTTP+import qualified Network.HTTP.Client.TLS as HTTP+#endif++ importDirectory :: FilePath importDirectory = "./dhall-lang/tests/import" @@ -44,17 +48,58 @@             , importDirectory </> "success/unit/asLocation/RemoteChain2A.dhall"             , importDirectory </> "success/unit/asLocation/RemoteChain3A.dhall"             , importDirectory </> "success/unit/asLocation/RemoteChainMissingA.dhall"++              -- Skip all tests that reference httpbin.org to avoid clobbering+              -- their servers.  These should eventually be replaced by tests+              -- that depend on an equivalent endpoint on test.dhall-lang.org+              -- instead of httpbin.org.+            , importDirectory </> "failure/customHeadersUsingBoundVariable.dhall"+            , importDirectory </> "failure/originHeadersFromRemote.dhall"+            , importDirectory </> "failure/originHeadersFromRemoteENV.dhall"+            , importDirectory </> "success/customHeadersA.dhall"+            , importDirectory </> "success/noHeaderForwardingA.dhall"+            , importDirectory </> "success/success/originHeadersA.dhall"+            , importDirectory </> "success/originHeadersENV.dhall"+            , importDirectory </> "success/originHeadersImportA.dhall"+            , importDirectory </> "success/originHeadersImportENV.dhall"+            , importDirectory </> "success/originHeadersImportFromEnvA.dhall"+            , importDirectory </> "success/originHeadersImportFromEnvENV.dhall"+            , importDirectory </> "success/originHeadersOverrideA.dhall"+            , importDirectory </> "success/originHeadersOverrideENV.dhall"             ] -    successTests <- Test.Util.discover (Turtle.chars <> "A.dhall") successTest (do+    successTests <- Test.Util.discover (Turtle.chars <* "A.dhall") successTest (do         path <- Turtle.lstree (importDirectory </> "success") -        Monad.guard (path `notElem` flakyTests)+        path `Test.Util.pathNotIn` flakyTests          return path ) -    failureTests <- Test.Util.discover (Turtle.chars <> ".dhall") failureTest (Turtle.lstree (importDirectory </> "failure"))+    failureTests <- Test.Util.discover (Turtle.chars <* ".dhall") failureTest (do+        path <- Turtle.lstree (importDirectory </> "failure") +        let expectedSuccesses =+                [ importDirectory </> "failure/unit/DontRecoverCycle.dhall"+                , importDirectory </> "failure/unit/DontRecoverTypeError.dhall"+#if !(defined(WITH_HTTP) && defined(NETWORK_TESTS))+                -- We attempt to simulate test.dhall-lang.org, but even so+                -- some tests unexpectedly succeed due to the inadequacy of+                -- the simulation+                , importDirectory </> "failure/unit/cors/OnlySelf.dhall"+                , importDirectory </> "failure/unit/cors/OnlyOther.dhall"+                , importDirectory </> "failure/unit/cors/Null.dhall"+                , importDirectory </> "failure/unit/cors/TwoHops.dhall"+                , importDirectory </> "failure/unit/cors/Empty.dhall"+                , importDirectory </> "failure/unit/cors/NoCORS.dhall"+                , importDirectory </> "failure/originHeadersFromRemote.dhall"+#endif+                ]++        path `Test.Util.pathNotIn` expectedSuccesses+        "ENV.dhall" `Test.Util.pathNotSuffixOf` path++        return path )+     let testTree =             Tasty.testGroup "import tests"                 [ successTests@@ -64,74 +109,131 @@     return testTree  successTest :: Text -> TestTree-successTest path = do-    let pathString = Text.unpack path+successTest prefix = do+    let inputPath = Text.unpack (prefix <> "A.dhall") -    let directoryString = FilePath.takeDirectory pathString+    let expectedPath = Text.unpack (prefix <> "B.dhall") -    let expectedFailures = []+    let directoryString = FilePath.takeDirectory inputPath -    Test.Util.testCase path expectedFailures (do+    let expectedFailures =+            [+              -- Importing relative to the home directory works, but I'm too+              -- lazy to mock the home directory for testing purposes+              importDirectory </> "success/unit/ImportRelativeToHome"+#if !(defined(WITH_HTTP) && defined(NETWORK_TESTS))+            , importDirectory </> "success/originHeadersImportFromEnv"+            , importDirectory </> "success/originHeadersImport"+            , importDirectory </> "success/originHeadersOverride"+            , importDirectory </> "success/unit/asLocation/RemoteChainEnv"+#endif+            ] -        text <- Text.IO.readFile pathString+    Test.Util.testCase prefix expectedFailures (do -        actualExpr <- Core.throws (Parser.exprFromText mempty text)+        text <- Text.IO.readFile inputPath -        let originalCache = "dhall-lang/tests/import/cache"+        expectedText <- Text.IO.readFile expectedPath -        let setCache = Turtle.export "XDG_CACHE_HOME"+        actualExpr <- Core.throws (Parser.exprFromText mempty text) -        let unsetCache = Turtle.unset "XDG_CACHE_HOME"+        expectedExpr <- Core.throws (Parser.exprFromText mempty expectedText) +        let originalCache = "dhall-lang/tests/import/cache"++#if defined(WITH_HTTP) && defined(NETWORK_TESTS)         let httpManager =                 HTTP.newManager                     HTTP.tlsManagerSettings                         { HTTP.managerResponseTimeout = HTTP.responseTimeoutMicro (120 * 1000 * 1000) }++        let status =+                Import.makeEmptyStatus+                    httpManager+                    (pure Import.envOriginHeaders)+                    directoryString+#else+        let status = Import.emptyStatus directoryString+#endif+         let load =                 State.evalStateT                     (Test.Util.loadWith actualExpr)-                    (Import.emptyStatusWithManager httpManager directoryString)+                    status -        let usesCache = [ "hashFromCacheA.dhall"-                        , "unit/asLocation/HashA.dhall"-                        , "unit/IgnorePoisonedCacheA.dhall"]+        let usesCache = [ "hashFromCache"+                        , "unit/asLocation/Hash"+                        , "unit/IgnorePoisonedCache"+                        , "unit/DontCacheIfHash"+                        ] -        let endsIn path' = not $ null $ Turtle.match (Turtle.ends path') path+        let endsIn path' =+                not (null (Turtle.match (Turtle.ends path') (Test.Util.toDhallPath prefix)))          let buildNewCache = do-                                tempdir <- Turtle.mktempdir "/tmp" "dhall-cache"-                                Turtle.liftIO $ Turtle.cptree originalCache tempdir-                                return tempdir+                tempdir <- Turtle.managed (Temp.withSystemTempDirectory "dhall-cache")+                Turtle.liftIO (Turtle.cptree originalCache tempdir)+                return tempdir -        let runTest =+        let cacheSetup =                 if any endsIn usesCache-                    then Turtle.runManaged $ do+                    then do                         cacheDir <- buildNewCache-                        setCache $ Turtle.format Turtle.fp cacheDir-                        _ <- Turtle.liftIO load-                        unsetCache-                    else do-                        _ <- load++                        let set = do+                                m <- Turtle.need "XDG_CACHE_HOME"++                                Turtle.export "XDG_CACHE_HOME" (Turtle.format Turtle.fp cacheDir)++                                return m++                        let reset Nothing = do+                                Turtle.unset "XDG_CACHE_HOME"+                            reset (Just x) = do+                                Turtle.export "XDG_CACHE_HOME" x++                        _ <- Turtle.managed (Exception.bracket set reset)                         return ()+                else pure () -        let handler :: SomeException -> IO ()+        let setup = cacheSetup >> Test.Util.managedTestEnvironment prefix++        let resolve = Turtle.with setup (const load)++        let handler :: SomeException -> IO (Core.Expr Parser.Src Void)             handler exception = Tasty.HUnit.assertFailure (show exception) -        Exception.handle handler runTest+        actualResolved <- Exception.handle handler resolve -        return () )+        expectedResolved <- Import.assertNoImports expectedExpr +        let actual = Core.normalize actualResolved :: Core.Expr Void Void++        let expected = Core.normalize expectedResolved :: Core.Expr Void Void++        let message =+                "The imported expression did not match the expected output"++        Tasty.HUnit.assertEqual message expected actual)+ failureTest :: Text -> TestTree-failureTest path = do+failureTest prefix = do+    let path = prefix <> ".dhall"+     let pathString = Text.unpack path      Tasty.HUnit.testCase pathString (do-        text <- Text.IO.readFile pathString+        actualExpr <- do+          Core.throws (Parser.exprFromText mempty (Test.Util.toDhallPath path)) -        actualExpr <- Core.throws (Parser.exprFromText mempty text)+        let setup = Test.Util.managedTestEnvironment prefix -        Exception.catch-          (do _ <- Test.Util.load actualExpr+        let run = Exception.catch @SomeException+              (Test.Util.load actualExpr >> return True)+              (\_ -> return False) -              fail "Import should have failed, but it succeeds")-          (\(SourcedException _ (MissingImports _)) -> pure ()) )+        succeeded <- Turtle.with setup (const run)++        if succeeded+            then fail "Import should have failed, but it succeeds"+            else return () )
tests/Dhall/Test/Lint.hs view
@@ -4,21 +4,19 @@  import Data.Text    (Text) import Dhall.Parser (Header (..))-import Prelude      hiding (FilePath) import Test.Tasty   (TestTree)-import Turtle       (FilePath) -import qualified Data.Text                             as Text-import qualified Data.Text.IO                          as Text.IO-import qualified Data.Text.Prettyprint.Doc             as Doc-import qualified Data.Text.Prettyprint.Doc.Render.Text as Doc.Render.Text-import qualified Dhall.Core                            as Core-import qualified Dhall.Lint                            as Lint-import qualified Dhall.Parser                          as Parser-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 Data.Text                 as Text+import qualified Data.Text.IO              as Text.IO+import qualified Dhall.Core                as Core+import qualified Dhall.Lint                as Lint+import qualified Dhall.Parser              as Parser+import qualified Dhall.Pretty              as Pretty+import qualified Dhall.Test.Util           as Test.Util+import qualified Prettyprinter             as Doc+import qualified Prettyprinter.Render.Text as Doc.Render.Text+import qualified Test.Tasty                as Tasty+import qualified Test.Tasty.HUnit          as Tasty.HUnit import qualified Turtle  lintDirectory :: FilePath
tests/Dhall/Test/Main.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} module Main where  import System.FilePath ((</>))@@ -5,18 +6,22 @@  import qualified Dhall.Test.Dhall import qualified Dhall.Test.Diff+import qualified Dhall.Test.DirectoryTree import qualified Dhall.Test.Format import qualified Dhall.Test.Freeze import qualified Dhall.Test.Import import qualified Dhall.Test.Lint import qualified Dhall.Test.Normalization+import qualified Dhall.Test.Package import qualified Dhall.Test.Parser import qualified Dhall.Test.QuickCheck import qualified Dhall.Test.Regression import qualified Dhall.Test.Schemas import qualified Dhall.Test.SemanticHash-import qualified Dhall.Test.Tags+#ifndef CROSS import qualified Dhall.Test.TH+#endif+import qualified Dhall.Test.Tags import qualified Dhall.Test.Tutorial import qualified Dhall.Test.TypeInference import qualified GHC.IO.Encoding@@ -62,11 +67,15 @@                 , tagsTests                 , freezeTests                 , schemaTests+                , Dhall.Test.DirectoryTree.tests                 , Dhall.Test.Regression.tests                 , Dhall.Test.Tutorial.tests                 , Dhall.Test.QuickCheck.tests                 , Dhall.Test.Dhall.tests+#ifndef CROSS                 , Dhall.Test.TH.tests+#endif+                , Dhall.Test.Package.tests                 ]      return testTree
tests/Dhall/Test/Normalization.hs view
@@ -2,12 +2,11 @@  module Dhall.Test.Normalization where -import Data.Text   (Text)-import Data.Void   (Void)-import Dhall.Core  (Expr (..), Var (..), throws)-import Prelude     hiding (FilePath)-import Test.Tasty  (TestTree)-import Turtle      (FilePath, (</>))+import Data.Text       (Text)+import Data.Void       (Void)+import Dhall.Core      (Expr (..), Var (..), throws)+import System.FilePath ((</>))+import Test.Tasty      (TestTree)  import qualified Data.Text        as Text import qualified Data.Text.IO     as Text.IO@@ -17,6 +16,7 @@ import qualified Dhall.Parser     as Parser import qualified Dhall.Test.Util  as Test.Util import qualified Dhall.TypeCheck  as TypeCheck+import qualified System.FilePath  as FilePath import qualified Test.Tasty       as Tasty import qualified Test.Tasty.HUnit as Tasty.HUnit import qualified Turtle@@ -24,32 +24,41 @@ normalizationDirectory :: FilePath normalizationDirectory = "./dhall-lang/tests/normalization/success" +unitDirectory :: FilePath+unitDirectory = normalizationDirectory </> "unit/"+ getTests :: IO TestTree getTests = do     let pattern = Turtle.chars <* "A.dhall"      let normalizationFiles = do-            path <- Turtle.lstree normalizationDirectory+            path <- FilePath.normalise <$> Turtle.lstree normalizationDirectory -            Nothing <- return (Turtle.stripPrefix (normalizationDirectory </> "unit/") path)+            unitDirectory `Test.Util.pathNotPrefixOf` path              return path      betaNormalizationTests <- Test.Util.discover pattern betaNormalizationTest normalizationFiles -    alphaNormalizationTests <- do+    alphaNormalizationTests <-         Test.Util.discover pattern alphaNormalizationTest             (Turtle.lstree "./dhall-lang/tests/alpha-normalization/success/") -    let unitTestFiles = Turtle.lstree (normalizationDirectory </> "unit/")+    let unitTestFiles = Turtle.lstree unitDirectory      unitTests <- Test.Util.discover pattern unitTest unitTestFiles      let testTree =             Tasty.testGroup "normalization"-                [ betaNormalizationTests-                , unitTests-                , alphaNormalizationTests+                [ Tasty.testGroup "beta-normalization"+                    [ betaNormalizationTests+                    ]+                , Tasty.testGroup "unit tests"+                    [ unitTests+                    ]+                , Tasty.testGroup "alpha-normalization"+                    [ alphaNormalizationTests+                    ]                 , customization                 ] @@ -67,7 +76,7 @@     let tyCtx =             Context.insert                 "min"-                (Pi "_" Natural (Pi "_" Natural Natural))+                (Pi mempty "_" Natural (Pi mempty "_" Natural Natural))                 Context.empty          valCtx e =@@ -128,7 +137,7 @@         let expectedNormalized = Core.denote expectedResolved :: Expr Void Void          let message =-                "The normalized expression did not match the expected output"+                "The alpha-normalized expression did not match the expected output"          Tasty.HUnit.assertEqual message expectedNormalized actualNormalized @@ -200,6 +209,6 @@                 Core.alphaNormalize (Core.denote expectedResolved)          let message =-                "The normalized expression did not match the expected output"+                "The beta-normalized expression did not match the expected output"          Tasty.HUnit.assertEqual message expectedNormalized actualNormalized
+ tests/Dhall/Test/Package.hs view
@@ -0,0 +1,270 @@+{-# LANGUAGE LambdaCase        #-}+{-# LANGUAGE OverloadedStrings #-}++module Dhall.Test.Package where++import           Control.Exception  (Exception, displayException, finally, try)+import           Data.List.NonEmpty (NonEmpty (..))+import           Data.Void          (Void)+import           Dhall.Core+    ( Directory (..)+    , Expr (..)+    , File (..)+    , FilePrefix (..)+    , Import (..)+    , ImportHashed (..)+    , ImportMode (..)+    , ImportType (..)+    , makeRecordField+    )+import qualified Dhall.Map          as Map+import           Dhall.Package+import           Lens.Micro         (set)+import qualified System.Directory   as Directory+import           System.FilePath    ((</>))+import           Test.Tasty+import           Test.Tasty.HUnit++tests :: TestTree+tests = testGroup "Package"+    [ packagePackageFile+    , packageCustomPackageFile+    , packageSingleFile+    , packageEmptyDirectory+    , packageSingleDirectory+    , packageNested+    , packageRecursive+    , packageMissingFile+    , packageFilesDifferentDirs+    , packageIncompatibleFiles+    ]++packagePackageFile :: TestTree+packagePackageFile = testCase "package file" $ do+    let path = "./tests/package" </> "package.dhall"++    let package :: Expr Void Import+        package = RecordLit Map.empty++    (output, expr) <- getPackagePathAndContent defaultOptions ("./tests/package/package.dhall" :| [])+    assertEqual "path" path output+    assertEqual "content" package expr++packageCustomPackageFile :: TestTree+packageCustomPackageFile = testCase "custom package file" $ do+    let path = "./tests/package" </> "custom.dhall"++    let package :: Expr Void Import+        package = RecordLit $+            Map.singleton "package" $ makeRecordField $ Embed packageDhall++    let options :: Options+        options = set packageFileName "custom.dhall" defaultOptions++    (output, expr) <- getPackagePathAndContent options ("./tests/package/package.dhall" :| [])+    assertEqual "path" path output+    assertEqual "content" package expr++packageSingleFile :: TestTree+packageSingleFile = testCase "single file" $ do+    let path = "./tests/package/dir" </> "package.dhall"++    let package :: Expr Void Import+        package = RecordLit $+            Map.singleton "test" $ makeRecordField $ Embed testDhall++    (output, expr) <- getPackagePathAndContent defaultOptions ("./tests/package/dir/test.dhall" :| [])+    assertEqual "path" path output+    assertEqual "content" package expr++packageEmptyDirectory :: TestTree+packageEmptyDirectory = testCase "empty directory" $ do+    let path = "./tests/package/empty" </> "package.dhall"++    let package :: Expr Void Import+        package = RecordLit Map.empty++    (output, expr) <- getPackagePathAndContent defaultOptions ("./tests/package/empty" :| [])+    assertEqual "path" path output+    assertEqual "content" package expr++packageSingleDirectory :: TestTree+packageSingleDirectory = testCase "single directory" $ do+    let path = "./tests/package/dir" </> "package.dhall"++    let package :: Expr Void Import+        package = RecordLit $ Map.singleton "test" $+            makeRecordField $ Embed testDhall++    (output, expr) <- getPackagePathAndContent defaultOptions ("./tests/package/dir" :| [])+    assertEqual "path" path output+    assertEqual "content" package expr++packageNested :: TestTree+packageNested = testCase "nested files" $ do+    let path = "./tests/package" </> "package.dhall"++    let package :: Expr Void Import+        package = RecordLit $ Map.fromList+            [ ("dir", makeRecordField $ RecordLit $ Map.fromList+                [ ("test", makeRecordField $ Embed dirTestDhall)+                ]+              )+            , ("other", makeRecordField $ Embed otherPackageDhall)+            , ("test", makeRecordField $ Embed testDhall)+            ]++    (output, expr) <- getPackagePathAndContent defaultOptions+        ( "./tests/package/test.dhall" :|+        [ "./tests/package/dir/test.dhall"+        , "./tests/package/other/package.dhall"+        ])+    assertEqual "path" path output+    assertEqual "content" package expr++packageRecursive :: TestTree+packageRecursive = testCase "recursively create subpackages" $ removePackagesAfter $ do+    let path = "./tests/package/dir" </> "package.dhall"++    let package :: Expr Void Import+        package = RecordLit $ Map.fromList+            [ ("subdirectory1", makeRecordField $ Embed subdirectoryPackageDhall1)+            , ("subdirectory2", makeRecordField $ Embed subdirectoryPackageDhall2)+            , ("test", makeRecordField $ Embed testDhall)+            ]++    let options :: Options+        options = set packagingMode RecursiveSubpackages defaultOptions++    (output, expr) <- getPackagePathAndContent options+        ( "./tests/package/dir" :| [] )+    assertEqual "path" path output+    assertEqual "content" package expr+    where+        removePackagesAfter :: IO a -> IO a+        removePackagesAfter action = action `finally` do+            Directory.removePathForcibly "./tests/package/dir/subdirectory1/package.dhall"+            Directory.removePathForcibly "./tests/package/dir/subdirectory2/package.dhall"++packageMissingFile :: TestTree+packageMissingFile = testCase "missing file" $ do+    let action :: IO (FilePath, Expr Void Import)+        action = getPackagePathAndContent defaultOptions ("./tests/package/missing.dhall" :| [])++    assertThrow action $ \case+        InvalidPath "./tests/package/missing.dhall" -> True+        _ -> False++packageFilesDifferentDirs :: TestTree+packageFilesDifferentDirs = testCase "files from different directories" $ do+    let action :: IO (FilePath, Expr Void Import)+        action = getPackagePathAndContent defaultOptions+            ( "./tests/package/dir/test.dhall" :|+            [ "./tests/package/test/test.dhall"+            ])++    assertThrow action $ \case+        AmbiguousOutputDirectory "./tests/package/dir" "./tests/package/test" -> True+        _ -> False++packageIncompatibleFiles :: TestTree+packageIncompatibleFiles = testCase "files that are incompatible" $ do+    let action :: IO (FilePath, Expr Void Import)+        action = getPackagePathAndContent defaultOptions+            ( "./tests/package/test.dhall" :|+            [ "./tests/package/test/test.dhall"+            ])++    assertThrow action $ \case+        IncompatiblePaths xs -> xs == [ testDhall , testTestDhall ]+        _ -> False++packageDhall :: Import+packageDhall = Import+    { importHashed = ImportHashed+        { hash = Nothing+        , importType = Local Here File+            { directory = Directory []+            , file = "package.dhall"+            }+        }+    , importMode = Code+    }++testDhall :: Import+testDhall = Import+    { importHashed = ImportHashed+        { hash = Nothing+        , importType = Local Here File+            { directory = Directory []+            , file = "test.dhall"+            }+        }+    , importMode = Code+    }++dirTestDhall :: Import+dirTestDhall = Import+    { importHashed = ImportHashed+        { hash = Nothing+        , importType = Local Here $ File+            { directory = Directory {components = ["dir"]}+            , file = "test.dhall"+            }+        }+    , importMode = Code+    }++otherPackageDhall :: Import+otherPackageDhall = Import+    { importHashed = ImportHashed+        { hash = Nothing+        , importType = Local Here $ File+            { directory = Directory {components = ["other"]}+            , file = "package.dhall"+            }+        }+    , importMode = Code+    }++subdirectoryPackageDhall1 :: Import+subdirectoryPackageDhall1 = Import+    { importHashed = ImportHashed+        { hash = Nothing+        , importType = Local Here $ File+            { directory = Directory {components = ["subdirectory1"]}+            , file = "package.dhall"}+            }+        , importMode = Code+        }++subdirectoryPackageDhall2 :: Import+subdirectoryPackageDhall2 = Import+    { importHashed = ImportHashed+        { hash = Nothing+        , importType = Local Here $ File+            { directory = Directory {components = ["subdirectory2"]}+            , file = "package.dhall"}+            }+        , importMode = Code+        }++testTestDhall :: Import+testTestDhall = Import+    { importHashed = ImportHashed+        { hash = Nothing+        , importType = Local Here (File+            { directory = Directory {components = ["test"]}+            , file = "test.dhall"+            })+        }+    , importMode = Code+    }++assertThrow :: (Exception e, Show a) => IO a -> (e -> Bool) -> IO ()+assertThrow k p = do+    result <- try k+    case result of+        Left e | p e -> return ()+        Left e -> assertFailure $ "Predicate did not match: " <> displayException e+        Right result' -> assertFailure $ "Expected exception, but got: " <> show result'
tests/Dhall/Test/Parser.hs view
@@ -2,12 +2,11 @@  module Dhall.Test.Parser where -import Data.Text   (Text)-import Data.Void   (Void)-import Dhall.Core  (Binding (..), Expr (..), Import, Var (..))-import Prelude     hiding (FilePath)-import Test.Tasty  (TestTree)-import Turtle      (FilePath, (</>))+import Data.Text       (Text)+import Data.Void       (Void)+import Dhall.Core      (Binding (..), Expr (..), Import, Var (..))+import System.FilePath ((</>))+import Test.Tasty      (TestTree)  import qualified Control.Monad        as Monad import qualified Data.Bifunctor       as Bifunctor@@ -152,7 +151,9 @@  shouldNotParse :: Text -> TestTree shouldNotParse path = do-    let expectedFailures = []+    let expectedFailures =+            [ parseDirectory </> "failure/spacing/LetNoSpace4.dhall"+            ]      let pathString = Text.unpack path 
tests/Dhall/Test/QuickCheck.hs view
@@ -1,3 +1,5 @@+-- TODO: update because we added ShowConstructor constructor to Expr in Dhall.Syntax+ {-# LANGUAGE CPP                 #-} {-# LANGUAGE DataKinds           #-} {-# LANGUAGE FlexibleInstances   #-}@@ -50,6 +52,7 @@     , Scheme (..)     , URL (..)     , Var (..)+    , WithComponent (..)     ) import Dhall.Map              (Map) @@ -62,7 +65,7 @@ import Dhall.Src                 (Src (..)) import Dhall.Test.Format         (format) import Dhall.TypeCheck           (TypeError, Typer)-import Generic.Random            ((:+) (..), ConstrGen (..), W, Weights, (%))+import Generic.Random            (ConstrGen (..), W, Weights, (%), (:+) (..)) import Test.QuickCheck     ( Arbitrary (..)     , Gen@@ -90,6 +93,7 @@ import qualified Data.Set import qualified Data.SpecialValues import qualified Data.Text             as Text+import qualified Data.Time             as Time import qualified Dhall.Binary import qualified Dhall.Context import qualified Dhall.Core@@ -99,7 +103,7 @@ import qualified Dhall.Set import qualified Dhall.TypeCheck import qualified Generic.Random-import qualified Lens.Family           as Lens+import qualified Lens.Micro            as Lens import qualified Numeric.Natural       as Nat import qualified Test.QuickCheck import qualified Test.Tasty@@ -270,14 +274,14 @@      shrink = genericShrink -instance (Arbitrary s, Arbitrary a) => Arbitrary (PreferAnnotation s a) where-    arbitrary =-        Test.QuickCheck.oneof-            [ pure PreferFromSource-            , PreferFromWith <$> arbitrary-            , pure PreferFromCompletion-            ]+instance Arbitrary PreferAnnotation where+    arbitrary = Test.QuickCheck.oneof+        [ pure PreferFromSource+        , pure PreferFromCompletion+        ] +    shrink = genericShrink+ instance (Arbitrary s, Arbitrary a) => Arbitrary (RecordField s a) where     arbitrary = lift4 RecordField @@ -295,6 +299,10 @@     arbitrary = FieldSelection <$> pure Nothing <*> label <*> pure Nothing     shrink = genericShrink +instance Arbitrary WithComponent where+    arbitrary =+        Test.QuickCheck.oneof [ pure WithQuestion, WithLabel <$> arbitrary ]+ instance (Arbitrary s, Arbitrary a) => Arbitrary (Expr s a) where     arbitrary =         Test.QuickCheck.suchThat@@ -305,10 +313,10 @@             standardizedExpression       where         customGens-            :: ConstrGen "Lam" 0 (FunctionBinding s a)-            :+ ConstrGen "Pi" 0 Text+            :: ConstrGen "Lam" 1 (FunctionBinding s a)+            :+ ConstrGen "Pi" 1 Text             :+ ConstrGen "Field" 1 (FieldSelection s)-            :+ ConstrGen "Project" 1 (Either (Set Text) (Expr s a))+            :+ ConstrGen "Project" 1 (Either [Text] (Expr s a))             :+ Gen Integer  -- Generates all Integer fields in Expr             :+ Gen Text     -- Generates all Text fields in Expr             :+ ()@@ -326,7 +334,7 @@          projection =             Test.QuickCheck.oneof-                [ fmap (Left . Dhall.Set.fromList) (Test.QuickCheck.listOf label)+                [ fmap Left (Test.QuickCheck.listOf label)                 , arbitrary                 ] @@ -350,6 +358,8 @@             % (1 :: W "BoolEQ")             % (1 :: W "BoolNE")             % (1 :: W "BoolIf")+            % (1 :: W "Bytes")+            % (1 :: W "BytesLit")             % (1 :: W "Natural")             % (7 :: W "NaturalLit")             % (1 :: W "NaturalFold")@@ -376,6 +386,15 @@             % (1 :: W "TextAppend")             % (1 :: W "TextReplace")             % (1 :: W "TextShow")+            % (1 :: W "Date")+            % (1 :: W "DateLiteral")+            % (1 :: W "DateShow")+            % (1 :: W "Time")+            % (1 :: W "TimeLiteral")+            % (1 :: W "TimeShow")+            % (1 :: W "TimeZone")+            % (1 :: W "TimeZoneLiteral")+            % (1 :: W "TimeZoneShow")             % (1 :: W "List")             % (1 :: W "ListLit")             % (1 :: W "ListAppend")@@ -398,6 +417,7 @@             % (7 :: W "RecordCompletion")             % (1 :: W "Merge")             % (1 :: W "ToMap")+            % (1 :: W "ShowConstructor")             % (7 :: W "Field")             % (7 :: W "Project")             % (1 :: W "Assert")@@ -417,13 +437,11 @@     Data.Sequence.null xs standardizedExpression (Note _ _) =     False-standardizedExpression (Combine (Just _) _ _) =+standardizedExpression (Combine _ (Just _) _ _) =     False standardizedExpression With{} =     False-standardizedExpression (Prefer PreferFromCompletion _ _) =-    False-standardizedExpression (Prefer (PreferFromWith _) _ _) =+standardizedExpression (Prefer _ PreferFromCompletion _ _) =     False -- The following three expressions are valid ASTs, but they can never be parsed, -- because the annotation will associate with `Merge`/`ListLit`/`ToMap` with@@ -434,16 +452,19 @@     False standardizedExpression (Annot (ToMap _ Nothing) _) =     False+standardizedExpression (TimeZoneLiteral (Time.TimeZone _ b t)) =+    not b && null t+standardizedExpression (TimeLiteral (Time.TimeOfDay _ _ ss) precision) =+    isInteger (ss * magnitude)+  where+    magnitude = 10 ^ precision++    isInteger x = x == fromInteger (round x) standardizedExpression _ =     True  chooseCharacter :: (Char, Char) -> Gen Char-chooseCharacter =-#if MIN_VERSION_QuickCheck(2,14,0)-    Test.QuickCheck.chooseEnum-#else-    Test.QuickCheck.choose-#endif+chooseCharacter = Test.QuickCheck.chooseEnum  instance Arbitrary File where     arbitrary = lift2 File@@ -508,7 +529,7 @@ -- The standard does not yet specify how to encode `as Text`, so don't test it -- yet instance Arbitrary ImportMode where-    arbitrary = Test.QuickCheck.elements [ Code, RawText, Location ]+    arbitrary = Test.QuickCheck.elements [ Code, RawText, Location, RawBytes ]      shrink = genericShrink 
tests/Dhall/Test/Regression.hs view
@@ -7,6 +7,7 @@  import Data.Either.Validation (Validation (..)) import Data.Void              (Void)+import Dhall.Core             (Expr (..), ReifiedNormalizer (..)) import Dhall.Import           (Imported, MissingImports (..)) import Dhall.Parser           (SourcedException (..), Src) import Dhall.TypeCheck        (TypeError)@@ -16,16 +17,17 @@ import qualified Control.Exception import qualified Data.Text.IO import qualified Data.Text.Lazy.IO-import qualified Data.Text.Prettyprint.Doc-import qualified Data.Text.Prettyprint.Doc.Render.Text import qualified Dhall-import qualified Dhall.Context+import qualified Dhall.Context             as Context import qualified Dhall.Core import qualified Dhall.Map import qualified Dhall.Parser import qualified Dhall.Pretty-import qualified Dhall.Test.Util                       as Util+import qualified Dhall.Test.Util           as Util import qualified Dhall.TypeCheck+import qualified Lens.Micro                as Lens+import qualified Prettyprinter+import qualified Prettyprinter.Render.Text import qualified System.Timeout import qualified Test.Tasty import qualified Test.Tasty.HUnit@@ -46,6 +48,9 @@         , issue1584         , issue1646         , issue1732+        , issue1884+        , issue2088+        , issue2463         , parsing0         , typeChecking0         , typeChecking1@@ -160,9 +165,9 @@     -- Verify that pretty-printing preserves string interpolation     source <- Data.Text.IO.readFile "./tests/regression/issue216b.dhall"     e <- Util.code source-    let doc       = Data.Text.Prettyprint.Doc.pretty e+    let doc       = Prettyprinter.pretty e     let docStream = Dhall.Pretty.layout doc-    let text0 = Data.Text.Prettyprint.Doc.Render.Text.renderLazy docStream+    let text0 = Prettyprinter.Render.Text.renderLazy docStream      text1 <- Data.Text.Lazy.IO.readFile "./tests/regression/issue216b.dhall" @@ -171,7 +176,7 @@ issue253 :: TestTree issue253 = Test.Tasty.HUnit.testCase "Issue #253" (do     -- Verify that type-checking rejects ill-formed custom contexts-    let context = Dhall.Context.insert "x" "x" Dhall.Context.empty+    let context = Context.insert "x" "x" Context.empty     let result = Dhall.TypeCheck.typeWith context "x"      -- If the context is not validated correctly then type-checking will@@ -221,6 +226,31 @@     -- expression as the first argument to a with expression     _ <- Util.code "./tests/regression/issue1884.dhall"     return () )++issue2088 :: TestTree+issue2088 = Test.Tasty.HUnit.testCase "Issue #2088" (do+    -- This test ensures that the parser for projection by labels doesn't+    -- accidentally swallow trailing commas OUTSIDE of the projection+    _ <- Util.code "./tests/regression/issue2088.dhall"+    return () )++issue2463 :: TestTree+issue2463 = Test.Tasty.HUnit.testCase "Issue #2463" (do+    let startingContext = Context.insert "foo" Integer Context.empty++    let normalizer (Var "foo") = Just (IntegerLit 0)+        normalizer  _          = Nothing++    let inputSettings = transform Dhall.defaultInputSettings+          where+            transform =+                  Lens.set Dhall.normalizer+                      (Just (ReifiedNormalizer (pure . normalizer)))+                . Lens.set Dhall.startingContext startingContext++    x <- Dhall.inputWithSettings inputSettings Dhall.auto "foo"++    Test.Tasty.HUnit.assertEqual "" (0 :: Integer) x )  parsing0 :: TestTree parsing0 = Test.Tasty.HUnit.testCase "Parsing regression #0" (
tests/Dhall/Test/Schemas.hs view
@@ -4,21 +4,19 @@  import Data.Text    (Text) import Dhall.Parser (Header (..))-import Prelude      hiding (FilePath) import Test.Tasty   (TestTree)-import Turtle       (FilePath) -import qualified Data.Text                             as Text-import qualified Data.Text.IO                          as Text.IO-import qualified Data.Text.Prettyprint.Doc             as Doc-import qualified Data.Text.Prettyprint.Doc.Render.Text as Doc.Render.Text-import qualified Dhall.Core                            as Core-import qualified Dhall.Parser                          as Parser-import qualified Dhall.Pretty                          as Pretty-import qualified Dhall.Schemas                         as Schemas-import qualified Dhall.Test.Util                       as Test.Util-import qualified Test.Tasty                            as Tasty-import qualified Test.Tasty.HUnit                      as Tasty.HUnit+import qualified Data.Text                 as Text+import qualified Data.Text.IO              as Text.IO+import qualified Dhall.Core                as Core+import qualified Dhall.Parser              as Parser+import qualified Dhall.Pretty              as Pretty+import qualified Dhall.Schemas             as Schemas+import qualified Dhall.Test.Util           as Test.Util+import qualified Prettyprinter             as Doc+import qualified Prettyprinter.Render.Text as Doc.Render.Text+import qualified Test.Tasty                as Tasty+import qualified Test.Tasty.HUnit          as Tasty.HUnit import qualified Turtle  schemasDirectory :: FilePath
tests/Dhall/Test/SemanticHash.hs view
@@ -2,10 +2,8 @@  module Dhall.Test.SemanticHash where -import Data.Text   (Text)-import Prelude     hiding (FilePath)-import Test.Tasty  (TestTree)-import Turtle      (FilePath)+import Data.Text  (Text)+import Test.Tasty (TestTree)  import qualified Data.Text        as Text import qualified Data.Text.IO     as Text.IO
tests/Dhall/Test/Substitution.hs view
@@ -11,7 +11,7 @@ import qualified Data.Either.Validation import qualified Dhall import qualified Dhall.Map-import qualified Lens.Family            as Lens+import qualified Lens.Micro             as Lens  data Result = Failure Integer | Success String     deriving (Eq, Dhall.Generic, Show)
tests/Dhall/Test/TH.hs view
@@ -1,15 +1,20 @@ {-# LANGUAGE DeriveAnyClass     #-} {-# LANGUAGE DeriveGeneric      #-} {-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE FlexibleInstances  #-} {-# LANGUAGE OverloadedStrings  #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TemplateHaskell    #-}  module Dhall.Test.TH where -import Dhall.TH   (HaskellType (..))-import Test.Tasty (TestTree)+import Control.Exception      (throwIO)+import Data.Either.Validation (Validation (..))+import Data.Time              (TimeOfDay (..), TimeZone (..), fromGregorian)+import Dhall.TH               (HaskellType (..))+import Test.Tasty             (TestTree) +import qualified Data.Text import qualified Dhall import qualified Dhall.TH import qualified Test.Tasty       as Tasty@@ -23,6 +28,7 @@ Dhall.TH.makeHaskellTypes     [ MultipleConstructors "Department" "./tests/th/Department.dhall"     , SingleConstructor "Employee" "MakeEmployee" "./tests/th/Employee.dhall"+    , SingleConstructor "TimeExample" "TimeExample" "./tests/th/Time.dhall"     ]  deriving instance Eq   Department@@ -31,6 +37,9 @@ deriving instance Eq   Employee deriving instance Show Employee +deriving instance Eq   TimeExample+deriving instance Show TimeExample+ Dhall.TH.makeHaskellTypes   [ SingleConstructor "Bar" "MakeBar" "(./tests/th/issue2066.dhall).Bar"   , SingleConstructor "Foo" "MakeFoo" "(./tests/th/issue2066.dhall).Foo"@@ -70,3 +79,141 @@     qux <- Dhall.input Dhall.auto "let T = ./tests/th/issue2066.dhall in T.Qux.Foo { foo = +2, bar = { baz = +3 } }"      Tasty.HUnit.assertEqual "" qux (Foo MakeFoo{ foo = 2, bar = MakeBar{ baz = 3 } })++    timex <- Dhall.input Dhall.auto "let T = ./tests/th/Time.dhall in { txTime = 21:12:00, txDate = 1976-04-01, txTimeZone = +05:00 } : T"++    Tasty.HUnit.assertEqual "" timex TimeExample { txTime = tod, txDate = day, txTimeZone = tz}++    where+      tod = TimeOfDay { todHour = 21, todMin = 12, todSec = 0 }+      day = fromGregorian 1976 4 1+      tz = TimeZone { timeZoneMinutes = 300, timeZoneSummerOnly = False, timeZoneName = "" }+  ++Dhall.TH.makeHaskellTypesWith (Dhall.TH.defaultGenerateOptions+    { Dhall.TH.constructorModifier = ("My" <>)+    , Dhall.TH.fieldModifier = ("my" <>) . Data.Text.toTitle+    })+    [ MultipleConstructors "MyT" "./tests/th/example.dhall"+    , MultipleConstructors "MyDepartment" "./tests/th/Department.dhall"+    , SingleConstructor "MyEmployee" "Employee" "./tests/th/Employee.dhall"+    ]++  +deriving instance Eq   MyT+deriving instance Eq   MyDepartment+deriving instance Eq   MyEmployee+deriving instance Show MyT+deriving instance Show MyDepartment+deriving instance Show MyEmployee++  +Dhall.TH.makeHaskellTypesWith (Dhall.TH.defaultGenerateOptions+    { Dhall.TH.constructorModifier = ("My" <>)+    , Dhall.TH.fieldModifier = ("my" <>) . Data.Text.toTitle+    , Dhall.TH.generateFromDhallInstance = False+    , Dhall.TH.generateToDhallInstance = False+    })+    [ SingleConstructor "MyHKSingle" "HKSingle" "./tests/th/HigherKindSingle.dhall"+    , MultipleConstructors "MyHKUnion" "./tests/th/HigherKindUnion.dhall"+    ]++type MyHKSingle_ = MyHKSingle Maybe Int+type MyHKUnion_ = MyHKUnion Bool Int++deriving instance Eq MyHKSingle_+deriving instance Show MyHKSingle_+deriving instance Dhall.Generic MyHKSingle_+instance Dhall.FromDhall MyHKSingle_+instance Dhall.ToDhall MyHKSingle_++deriving instance Eq MyHKUnion_+deriving instance Show MyHKUnion_+deriving instance Dhall.Generic MyHKUnion_+instance Dhall.FromDhall MyHKUnion_+instance Dhall.ToDhall MyHKUnion_++testMakeHaskellTypesWith :: TestTree+testMakeHaskellTypesWith = Tasty.HUnit.testCase "makeHaskellTypesWith" $ do+    let text0 = "let T = ./tests/th/example.dhall in T.A { x = True, y = [] : List Text }"+        ref0 = MyA{ myX = True, myY = [] }+    myTest text0 ref0++    let text1 = "let T = ./tests/th/example.dhall in T.B (None (List Natural))"+        ref1 = MyB Nothing+    myTest text1 ref1++    let text2 = "let T = ./tests/th/example.dhall in T.C"+        ref2 = MyC+    myTest text2 ref2++    let textDepartment = "let T = ./tests/th/Department.dhall in T.Sales"+        refDepartment = MySales+    myTest textDepartment refDepartment++    let textEmployee = "let T = ./tests/th/Department.dhall in T.Sales"+        refEmployee = MyEmployee{ myName = "", myDepartment = MySales }+    myTest textEmployee refEmployee++    let textHKSingle = "let T = (./tests/th/HigherKindSingle.dhall) Optional Int in T { foo = +1, bar = Some +2, bam = \"\" }"+        refHKSingle = MyHKSingle { myFoo = 1, myBar = Just 2, myBam = "" } :: MyHKSingle_+    myTest textHKSingle refHKSingle++    let textHKUnion0 = "let T = (./tests/th/HigherKindUnion.dhall) Bool Int in T.Foo True"+        refHKUnion0 = MyFoo True :: MyHKUnion_+    myTest textHKUnion0 refHKUnion0++    let textHKUnion1 = "let T = (./tests/th/HigherKindUnion.dhall) Bool Int in T.Bar +1"+        refHKUnion1 = MyBar 1 :: MyHKUnion_+    myTest textHKUnion1 refHKUnion1++    where+        myTest text ref = do+            expr <- Dhall.inputExpr text+            t <- case Dhall.extract Dhall.auto expr of+                Failure e -> throwIO e+                Success t -> return t++            Tasty.HUnit.assertEqual "" t ref+            Tasty.HUnit.assertEqual "" expr $ Dhall.embed Dhall.inject ref++Dhall.TH.makeHaskellTypesWith (Dhall.TH.defaultGenerateOptions+    { Dhall.TH.constructorModifier = ("NoFromDhall" <>)+    , Dhall.TH.fieldModifier = ("noFromDhall" <>) . Data.Text.toTitle+    , Dhall.TH.generateFromDhallInstance = False+    })+    [ MultipleConstructors "NoFromDhallT" "./tests/th/example.dhall"+    ]++instance Dhall.FromDhall NoFromDhallT++Dhall.TH.makeHaskellTypesWith (Dhall.TH.defaultGenerateOptions+    { Dhall.TH.constructorModifier = ("NoToDhall" <>)+    , Dhall.TH.fieldModifier = ("noToDhall" <>) . Data.Text.toTitle+    , Dhall.TH.generateToDhallInstance = False+    })+    [ MultipleConstructors "NoToDhallT" "./tests/th/example.dhall"+    ]++instance Dhall.ToDhall NoToDhallT++Dhall.TH.makeHaskellTypesWith (Dhall.TH.defaultGenerateOptions+    { Dhall.TH.constructorModifier = ("NoInstances" <>)+    , Dhall.TH.fieldModifier = ("noInstances" <>) . Data.Text.toTitle+    , Dhall.TH.generateFromDhallInstance = False+    , Dhall.TH.generateToDhallInstance = False+    })+    [ MultipleConstructors "NoInstancesT" "./tests/th/example.dhall"+    ]++deriving instance Dhall.Generic NoInstancesT+instance Dhall.FromDhall NoInstancesT+instance Dhall.ToDhall NoInstancesT++Dhall.TH.makeHaskellTypesWith (Dhall.TH.defaultGenerateOptions+    { Dhall.TH.constructorModifier = ("Strict" <>)+    , Dhall.TH.fieldModifier = ("strict" <>) . Data.Text.toTitle+    , Dhall.TH.makeStrict = True+    })+    [ MultipleConstructors "StrictFields" "./tests/th/example.dhall"+    ]
tests/Dhall/Test/Tags.hs view
@@ -2,11 +2,10 @@  module Dhall.Test.Tags where -import Data.Text   (Text)-import Dhall.Util  (Input (..))-import Prelude     hiding (FilePath)-import Test.Tasty  (TestTree)-import Turtle      (FilePath)+import Data.Text       (Text)+import Dhall.Util      (Input (..))+import System.FilePath ((</>))+import Test.Tasty      (TestTree)  import qualified Data.Text        as Text import qualified Data.Text.IO     as Text.IO@@ -30,7 +29,9 @@ tagsTest :: Text -> TestTree tagsTest prefix =     Tasty.HUnit.testCase (Text.unpack prefix) $ do-        let inputFile  = Text.unpack (prefix <> ".dhall")+        -- The use of toDhallPah is a hack to ensure we always get the same file+        -- paths, i.e. ones with a '.' prefixed and UNIX path separators.+        let inputFile  = Text.unpack (Test.Util.toDhallPath prefix <> ".dhall")         let outputFile = Text.unpack (prefix <> ".tags")          actualTags <- fixPathSeparators <$> Tags.generate (InputFile inputFile) Nothing False@@ -44,7 +45,7 @@ tagsDirTest :: TestTree tagsDirTest =     Tasty.HUnit.testCase "all" $ do-        let outputFile = Text.unpack . Turtle.format Turtle.fp $ tagsDirectory Turtle.</> "all.tags"+        let outputFile = Text.unpack . Turtle.format Turtle.fp $ tagsDirectory </> "all.tags"          actualTags <- fmap fixPathSeparators                       (Tags.generate
tests/Dhall/Test/TypeInference.hs view
@@ -5,12 +5,10 @@  import Control.Exception (SomeException (..)) import Data.Text         (Text)-import Prelude           hiding (FilePath)+import System.FilePath   ((</>)) import Test.Tasty        (TestTree)-import Turtle            (FilePath, (</>))  import qualified Control.Exception as Exception-import qualified Control.Monad     as Monad import qualified Data.Text         as Text import qualified Data.Text.IO      as Text.IO import qualified Dhall.Core        as Core@@ -38,7 +36,7 @@                     , typeInferenceDirectory </> "success/CacheImportsCanonicalizeA.dhall"                     ] -            Monad.guard (path `notElem` skip)+            path `Test.Util.pathNotIn` skip              return path @@ -59,7 +57,7 @@ successTest prefix = do     let expectedFailures =                 []-#ifdef WITH_HTTP+#if defined(WITH_HTTP) && defined(NETWORK_TESTS) #else             ++  [ typeInferenceDirectory </> "success/CacheImports"                 ]@@ -97,14 +95,18 @@          Tasty.HUnit.assertEqual message resolvedExpectedType inferredType +        -- We also add this to exercise the `Dhall.Eval.conv` code path, since+        -- it's easy to forget to update it when adding new syntax+        _ <- Core.throws (TypeCheck.typeOf (Core.Annot resolvedExpr resolvedExpectedType))+        return ()+ failureTest :: Text -> TestTree failureTest prefix = do     let expectedFailures =                [                -- Duplicate fields are incorrectly caught during parsing:                -- https://github.com/dhall-lang/dhall-haskell/issues/772-                 typeInferenceDirectory </> "failure/unit/RecordProjectionDuplicateFields"-               , typeInferenceDirectory </> "failure/unit/RecordTypeDuplicateFields"+                 typeInferenceDirectory </> "failure/unit/RecordTypeDuplicateFields"                , typeInferenceDirectory </> "failure/unit/UnionTypeDuplicateVariants1"                , typeInferenceDirectory </> "failure/unit/UnionTypeDuplicateVariants2"                ]
tests/Dhall/Test/Util.hs view
@@ -1,6 +1,8 @@ {-# LANGUAGE CPP               #-}+{-# LANGUAGE NamedFieldPuns    #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RankNTypes        #-}+{-# LANGUAGE ViewPatterns      #-}  module Dhall.Test.Util     ( code@@ -18,35 +20,47 @@     , assertDoesntTypeCheck     , discover     , Dhall.Test.Util.testCase+    , pathIn+    , pathNotIn+    , pathNotPrefixOf+    , pathNotSuffixOf     , toDhallPath+    , managedTestEnvironment     ) where +import Control.Applicative              (Alternative, liftA2, (<|>))+import Control.Exception                (tryJust)+import Control.Monad                    (guard) import Control.Monad.Trans.State.Strict (StateT) import Data.Bifunctor                   (first) import Data.Text                        (Text) import Data.Void                        (Void) import Dhall.Context                    (Context) import Dhall.Core-    ( Expr+    ( Chunks (..)+    , Expr (..)     , Import     , Normalizer     , ReifiedNormalizer (..)     ) import Dhall.Import                     (SemanticCacheMode (..), Status (..)) import Dhall.Parser                     (Src)-import Prelude                          hiding (FilePath)+import System.IO.Error                  (isDoesNotExistError) import Test.Tasty                       (TestTree) import Test.Tasty.HUnit-import Turtle                           (FilePath, Pattern, Shell, fp)+import Turtle                           (Pattern, Shell, fp)  import qualified Control.Exception import qualified Control.Foldl                    as Foldl import qualified Control.Monad.Trans.State.Strict as State import qualified Data.Functor+import qualified Data.List                        as List import qualified Data.Text                        as Text+import qualified Data.Text.IO                     as Text.IO import qualified Dhall.Context import qualified Dhall.Core import qualified Dhall.Import+import qualified Dhall.Map import qualified Dhall.Parser import qualified Dhall.TypeCheck import qualified System.FilePath                  as FilePath@@ -54,10 +68,12 @@ import qualified Test.Tasty.ExpectedFailure       as Tasty.ExpectedFailure import qualified Turtle -#ifndef WITH_HTTP-import Control.Monad.IO.Class   (MonadIO (..))-import Dhall.Core               (URL (..))-import Lens.Family.State.Strict (zoom)+#if defined(WITH_HTTP) && defined(NETWORK_TESTS)+import qualified Data.Foldable+#else+import Control.Monad.IO.Class (MonadIO (..))+import Dhall.Core             (Directory (..), File (..), URL (..))+import Lens.Micro.Mtl         (zoom)  import qualified Data.Foldable import qualified Data.Text.Encoding@@ -94,62 +110,85 @@         (loadWith expression)         (Dhall.Import.emptyStatus rootDirectory) { _semanticCacheMode = semanticCacheMode } -#ifdef WITH_HTTP+#if defined(WITH_HTTP) && defined(NETWORK_TESTS) loadWith :: Expr Src Import -> StateT Status IO (Expr Src Void) loadWith = Dhall.Import.loadWith  #else loadWith :: Expr Src Import -> StateT Status IO (Expr Src Void) loadWith expr = do-    let mockRemote' url = do-            liftIO . putStrLn $ "\nTesting without real HTTP support --"-                ++ " using mock HTTP client to resolve remote import."-            mockRemote url-    zoom Dhall.Import.remote (State.put mockRemote')+    zoom Dhall.Import.remote (State.put mockRemote)     Dhall.Import.loadWith expr  mockRemote :: Dhall.Core.URL -> StateT Status IO Data.Text.Text--- Matches anything pointing to--- `https://raw.githubusercontent.com/dhall-lang/dhall-lang/master/`-mockRemote (URL { authority = "raw.githubusercontent.com"-                , path = Dhall.Core.File (Dhall.Core.Directory components) file })-  | take 3 (reverse components) == ["dhall-lang", "dhall-lang", "master"] = do-    let dropEnd n ls = take (length ls - n) ls-    let localDir = dropEnd 3 components ++ ["dhall-lang"]+mockRemote+    url@URL+        { authority = "raw.githubusercontent.com"+        , path = File (Directory components) file+        } = do+    let localDir = case reverse components of+            "dhall-lang" : "dhall-lang" : _ : rest ->+                reverse ("dhall-lang" : rest)+            "Nadrieril" : "dhall-rust" : _ : "dhall" : rest ->+                reverse ("dhall-lang" : rest)+            _ -> do+                fail ("Unable to mock URL: " <> Text.unpack (Dhall.Core.pretty url)) -    localPath <- Dhall.Import.localToPath Dhall.Core.Here (Dhall.Core.File (Dhall.Core.Directory localDir) file)-    liftIO $ Data.Text.IO.readFile localPath+    localPath <- Dhall.Import.localToPath Dhall.Core.Here (File (Directory localDir) file) --- Matches anything pointing to--- `https://test.dhall-lang.org/Bool/package.dhall`; checks that a `test` header--- is present and redirects to the local copy of the prelude.-mockRemote (URL { authority = "test.dhall-lang.org"-                , path = Dhall.Core.File (Dhall.Core.Directory components) file-                , headers = Just headersExpr }) =-    case Data.Foldable.find ((== "test") . fst) hs of-        Nothing -> fail $ "(mock http) Tried to load an import from "-                          ++"\"test.dhall-lang.org\""-                          ++ "without setting the \"test\" header field."-        Just (_, _) -> do-            let localDir = components ++ ["Prelude", "dhall-lang"]-            localPath <- Dhall.Import.localToPath Dhall.Core.Here (Dhall.Core.File (Dhall.Core.Directory localDir) file)-            liftIO $ Data.Text.IO.readFile localPath-  where-    hs = Dhall.Import.toHeaders headersExpr+    liftIO (Data.Text.IO.readFile localPath) --- Emulates `https://httpbin.org/user-agent`-mockRemote (URL { authority = "httpbin.org"-                , path = Dhall.Core.File (Dhall.Core.Directory []) "user-agent"-                , headers = Just headersExpr }) =-    case Data.Foldable.find ((== "user-agent") . fst) hs of-        Nothing -> fail $ "(mock http) Tried to read the user agent via "-                          ++ "\"httpbin.com/user-agent\" without supplying one "-                          ++ "in the header!"-        Just (_, userAgent) -> do+mockRemote+    URL { authority = "prelude.dhall-lang.org"+        , path = File (Directory components) file+        } = do+    let localDir = components ++ [ "Prelude", "dhall-lang" ]++    localPath <- Dhall.Import.localToPath Dhall.Core.Here (File (Directory localDir) file)++    liftIO (Data.Text.IO.readFile localPath)++mockRemote url@URL{ authority = "test.dhall-lang.org", path, headers } =+    case (path, fmap Dhall.Import.toHeaders headers) of+        (File (Directory []) "foo", Just [("test", _)]) ->+            return "./bar"+        (File (Directory []) "bar", Just [("test", _)]) ->+            return "True"+        (File (Directory ["cors"]) "AllowedAll.dhall", _) ->+            return "42"+        (File (Directory ["cors"]) "OnlyGithub.dhall", _) ->+            return "42"+        (File (Directory ["cors"]) "OnlySelf.dhall", _) ->+            return "42"+        (File (Directory ["cors"]) "OnlyOther.dhall", _) ->+            return "42"+        (File (Directory ["cors"]) "Empty.dhall", _) ->+            return "42"+        (File (Directory ["cors"]) "NoCORS.dhall", _) ->+            return "42"+        (File (Directory ["cors"]) "Null.dhall", _) ->+            return "42"+        (File (Directory ["cors"]) "SelfImportAbsolute.dhall", _) ->+            return "https://test.dhall-lang.org/cors/NoCORS.dhall"+        (File (Directory ["cors"]) "SelfImportRelative.dhall", _) ->+            return "./NoCORS.dhall"+        (File (Directory ["cors"]) "TwoHopsFail.dhall", _) ->+            return "https://raw.githubusercontent.com/dhall-lang/dhall-lang/5ff7ecd2411894dd9ce307dc23020987361d2d43/tests/import/data/cors/OnlySelf.dhall"+        (File (Directory ["cors"]) "TwoHopsSuccess.dhall", _) ->+            return "https://raw.githubusercontent.com/dhall-lang/dhall-lang/5ff7ecd2411894dd9ce307dc23020987361d2d43/tests/import/data/cors/OnlyGithub.dhall"+        _ -> do+            fail ("Unable to mock URL: " <> Text.unpack (Dhall.Core.pretty url))++mockRemote url@URL{ authority = "httpbin.org", path, headers } =+    case (path, fmap Dhall.Import.toHeaders headers) of+        (File (Directory []) "user-agent", Just [("user-agent", userAgent)]) -> do             let agentText = Data.Text.Encoding.decodeUtf8 userAgent+             return ("{\n  \"user-agent\": \"" <> agentText <> "\"\n}\n")-  where-    hs = Dhall.Import.toHeaders headersExpr+        (File (Directory []) "user-agent", Nothing) -> do+            return ("{\n  \"user-agent\": \"Dhall\"\n}\n")+        _ -> do+            fail ("Unable to mock URL: " <> Text.unpack (Dhall.Core.pretty url))  mockRemote url = do     let urlString = Text.unpack (Dhall.Core.pretty url)@@ -157,6 +196,57 @@         <> urlString) #endif +{- Given a test prefix, returns a managed resource+   which sets / reverts relevant environment variables based+   on `prefix <> "ENV.dhall"` (if present)+ -}+managedTestEnvironment :: Text -> Turtle.Managed [(Text, Maybe Text)]+managedTestEnvironment prefix = Turtle.managed (Control.Exception.bracket setup cleanup)+  where+    envPath = Text.unpack (prefix <> "ENV.dhall")++    setup :: IO [(Text, Maybe Text)]+    setup = do+        envFileContents <-+            tryJust (guard . isDoesNotExistError) (Text.IO.readFile envPath)++        testEnv <- case envFileContents of+            Right contents -> do+                resolved <- code contents+                return (convertEnvExpr (Dhall.Core.normalize resolved))+            Left _ -> return []++        traverse setEnv testEnv++    cleanup :: [(Text, Maybe Text)] -> IO ()+    cleanup = Data.Foldable.traverse_ restoreEnv++    convertEnvExpr :: Expr Src Void -> [(Text, Text)]+    convertEnvExpr (ListLit _ hs) = Data.Foldable.toList (Data.Foldable.fold maybePairs)+      where+          maybePairs = mapM toPair hs++          toPair :: Expr s a -> Maybe (Text, Text)+          toPair (RecordLit m) = do+              (Dhall.Core.recordFieldValue -> TextLit (Chunks [] key), Dhall.Core.recordFieldValue -> TextLit (Chunks [] value))+                  <- lookupHeader <|> lookupMapKey+              return (key, value)+                where+                  lookupHeader = liftA2 (,) (Dhall.Map.lookup "header" m) (Dhall.Map.lookup "value" m)+                  lookupMapKey = liftA2 (,) (Dhall.Map.lookup "mapKey" m) (Dhall.Map.lookup "mapValue" m)+          toPair _ = Nothing+    convertEnvExpr _ = []++    setEnv :: (Text, Text) -> IO (Text, Maybe Text)+    setEnv (k, v) = do+        old <- Turtle.need k+        Turtle.export k v+        return (k, old)++    restoreEnv :: (Text, Maybe Text) -> IO ()+    restoreEnv (k, Just old) = Turtle.export k old+    restoreEnv (k, Nothing) = Turtle.unset k+ equivalent :: Text -> Text -> IO () equivalent text0 text1 = do     expr0 <- fmap Dhall.Core.normalize (code text0) :: IO (Expr Void Void)@@ -203,7 +293,7 @@     let shell = do             path_ <- paths -            let pathText = Turtle.format fp path_+            let pathText = Turtle.format fp (FilePath.normalise path_)              prefix : _ <- return (Turtle.match pattern pathText) @@ -215,15 +305,29 @@  testCase :: Text -> [ FilePath ] -> Assertion -> TestTree testCase prefix expectedFailures assertion =-    if prefix `elem` map (Turtle.format fp) expectedFailures+    if prefix `elem` map (Turtle.format fp . FilePath.normalise) expectedFailures     then Tasty.ExpectedFailure.expectFail test     else test   where     test = Test.Tasty.HUnit.testCase (Text.unpack prefix) assertion +pathIn :: Alternative f => FilePath -> [FilePath] -> f ()+pathIn this = guard . any (FilePath.equalFilePath this)++pathNotIn :: Alternative f => FilePath -> [FilePath] -> f ()+pathNotIn this = guard . not . any (FilePath.equalFilePath this)++pathNotPrefixOf :: Alternative f => FilePath -> FilePath -> f ()+pathNotPrefixOf this =+    guard . not . List.isPrefixOf (FilePath.normalise this) . FilePath.normalise++pathNotSuffixOf :: Alternative f => FilePath -> FilePath -> f ()+pathNotSuffixOf this =+    guard . not . List.isSuffixOf (FilePath.normalise this) . FilePath.normalise+ {-| Path names on Windows are not valid Dhall paths due to using backslashes     instead of forwardslashes to separate path components.  This utility fixes     them if necessary -} toDhallPath :: Text -> Text-toDhallPath = Text.replace "\\" "/"+toDhallPath = ("./" <>) . Text.replace "\\" "/"
tests/format/ipfsB.dhall view
@@ -11,7 +11,8 @@       labels.{ `app.kubernetes.io/name`, `app.kubernetes.io/instance` }  let k8s =-      https://raw.githubusercontent.com/dhall-lang/dhall-kubernetes/4ab28225a150498aef67c226d3c5f026c95b5a1e/package.dhall sha256:2c7ac35494f16b1f39afcf3467b2f3b0ab579edb0c711cddd2c93f1cbed358bd+      https://raw.githubusercontent.com/dhall-lang/dhall-kubernetes/4ab28225a150498aef67c226d3c5f026c95b5a1e/package.dhall+        sha256:2c7ac35494f16b1f39afcf3467b2f3b0ab579edb0c711cddd2c93f1cbed358bd  let serviceName = "ipfs" 
tests/format/issue1400-2B.dhall view
@@ -3,7 +3,8 @@     = λ(a : Type) →         { field : Text         , nesting :-              ./Nesting sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335+              ./Nesting+                sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335             ? ./Nesting         , contents : a         }
+ tests/format/issue2078A.dhall view
@@ -0,0 +1,1 @@+"'\${x}'\n"
+ tests/format/issue2078B.dhall view
@@ -0,0 +1,3 @@+''+${"'"}''${x}'+''
+ tests/format/issue2601A.dhall view
@@ -0,0 +1,11 @@+let T = < Some | Type >++let t+    : T+    = T.`Some`++let x+    : T+    = T.Type++in  True
+ tests/format/issue2601B.dhall view
@@ -0,0 +1,11 @@+let T = < Some | Type >++let t+    : T+    = T.`Some`++let x+    : T+    = T.Type++in  True
+ tests/format/letAnnotatedShortA.dhall view
@@ -0,0 +1,1 @@+let empty : ∀(a : Type) → List a = λ(a : Type) → [] : List a in empty
+ tests/format/letAnnotatedShortB.dhall view
@@ -0,0 +1,5 @@+let empty+    : ∀(a : Type) → List a+    = λ(a : Type) → [] : List a++in  empty
+ tests/format/negativeTimeZoneA.dhall view
@@ -0,0 +1,1 @@+04:00:00-04:00
+ tests/format/negativeTimeZoneB.dhall view
@@ -0,0 +1,1 @@+04:00:00-04:00
tests/format/numericLiteralsA.dhall view
@@ -1,1 +1,1 @@-{ example0 = 0x42, example1 = +0x42, example2 = 1.2e20 }+{ example0 = 0x42, example1 = +0x42, example2 = 1.2e20, example3 = -0b0111 }
tests/format/numericLiteralsB.dhall view
@@ -1,1 +1,1 @@-{ example0 = 0x42, example1 = +0x42, example2 = 1.2e20 }+{ example0 = 0x42, example1 = +0x42, example2 = 1.2e20, example3 = -0b0111 }
+ tests/format/parenthesizeUsingA.dhall view
@@ -0,0 +1,6 @@+-- https://github.com/dhall-lang/dhall-haskell/issues/2273+let MyPackage =+      https://server.test/package.dhall using (./headers.dhall)+        sha256:03a6e298ff140d430cea8b387fad886ce9f5bee24622c7d1102115cc08ed9cf8++in  MyPackage
+ tests/format/parenthesizeUsingB.dhall view
@@ -0,0 +1,6 @@+-- https://github.com/dhall-lang/dhall-haskell/issues/2273+let MyPackage =+      https://server.test/package.dhall using (./headers.dhall)+        sha256:03a6e298ff140d430cea8b387fad886ce9f5bee24622c7d1102115cc08ed9cf8++in  MyPackage
+ tests/format/preserveShebangA.dhall view
@@ -0,0 +1,2 @@+#!/usr/bin/env -S dhall text --file+"Hello, world!"
+ tests/format/preserveShebangB.dhall view
@@ -0,0 +1,2 @@+#!/usr/bin/env -S dhall text --file+"Hello, world!"
tests/format/sha256PrintingB.dhall view
@@ -1,4 +1,5 @@ let replicate =-      https://raw.githubusercontent.com/dhall-lang/Prelude/c79c2bc3c46f129cc5b6d594ce298a381bcae92c/List/replicate sha256:cc856d59b63f7699881bdb8e4b1036ca4c0013827268040a50c1e1405f646a2c+      https://raw.githubusercontent.com/dhall-lang/Prelude/c79c2bc3c46f129cc5b6d594ce298a381bcae92c/List/replicate+        sha256:cc856d59b63f7699881bdb8e4b1036ca4c0013827268040a50c1e1405f646a2c  in  replicate 5
+ tests/format/timePrecisionA.dhall view
@@ -0,0 +1,3 @@+-- This test ensures that we don't strip leading zeros from the fractional+-- component of seconds when pretty-printing them+00:00:00.01
+ tests/format/timePrecisionB.dhall view
@@ -0,0 +1,3 @@+-- This test ensures that we don't strip leading zeros from the fractional+-- component of seconds when pretty-printing them+00:00:00.01
+ tests/format/withQuestionA.dhall view
@@ -0,0 +1,1 @@+λ(x : Optional Natural) → x with ? = 2
+ tests/format/withQuestionB.dhall view
@@ -0,0 +1,1 @@+λ(x : Optional Natural) → x with ? = 2
− tests/freeze/True.dhall
@@ -1,1 +0,0 @@-True
+ tests/freeze/cached/True.dhall view
@@ -0,0 +1,1 @@+True
+ tests/freeze/cached/cachedA.dhall view
@@ -0,0 +1,2 @@+  ./True.dhall sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70+? ./True.dhall
+ tests/freeze/cached/cachedB.dhall view
@@ -0,0 +1,3 @@+  missing+    sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70+? ./True.dhall
+ tests/freeze/cached/idempotentA.dhall view
@@ -0,0 +1,5 @@+-- The purpose of this test is to verify that `dhall freeze --cached` is+-- idempotent and doesn't attempt to resolve the `missing` import+  missing+    sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70+? ./True.dhall
+ tests/freeze/cached/idempotentB.dhall view
@@ -0,0 +1,3 @@+  missing+    sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70+? ./True.dhall
+ tests/freeze/cached/incorrectHashA.dhall view
@@ -0,0 +1,1 @@+./True.dhall sha256:0000000000000000000000000000000000000000000000000000000000000000
+ tests/freeze/cached/incorrectHashB.dhall view
@@ -0,0 +1,3 @@+  missing+    sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70+? ./True.dhall
+ tests/freeze/cached/protectedA.dhall view
@@ -0,0 +1,1 @@+./True.dhall sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
+ tests/freeze/cached/protectedB.dhall view
@@ -0,0 +1,3 @@+  missing+    sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70+? ./True.dhall
+ tests/freeze/cached/unprotectedA.dhall view
@@ -0,0 +1,1 @@+./True.dhall
+ tests/freeze/cached/unprotectedB.dhall view
@@ -0,0 +1,3 @@+  missing+    sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70+? ./True.dhall
− tests/freeze/cachedA.dhall
@@ -1,2 +0,0 @@-  ./True.dhall sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70-? ./True.dhall
− tests/freeze/cachedB.dhall
@@ -1,2 +0,0 @@-  ./True.dhall sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70-? ./True.dhall
− tests/freeze/incorrectHashA.dhall
@@ -1,1 +0,0 @@-./True.dhall sha256:0000000000000000000000000000000000000000000000000000000000000000
− tests/freeze/incorrectHashB.dhall
@@ -1,2 +0,0 @@-  ./True.dhall sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70-? ./True.dhall
− tests/freeze/protectedA.dhall
@@ -1,1 +0,0 @@-./True.dhall sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
− tests/freeze/protectedB.dhall
@@ -1,2 +0,0 @@-  ./True.dhall sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70-? ./True.dhall
+ tests/freeze/secure/True.dhall view
@@ -0,0 +1,1 @@+True
+ tests/freeze/secure/cachedA.dhall view
@@ -0,0 +1,2 @@+  ./True.dhall sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70+? ./True.dhall
+ tests/freeze/secure/cachedB.dhall view
@@ -0,0 +1,2 @@+./True.dhall+  sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
+ tests/freeze/secure/incorrectHashA.dhall view
@@ -0,0 +1,1 @@+./True.dhall sha256:0000000000000000000000000000000000000000000000000000000000000000
+ tests/freeze/secure/incorrectHashB.dhall view
@@ -0,0 +1,2 @@+./True.dhall+  sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
+ tests/freeze/secure/protectedA.dhall view
@@ -0,0 +1,1 @@+./True.dhall sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
+ tests/freeze/secure/protectedB.dhall view
@@ -0,0 +1,2 @@+./True.dhall+  sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
+ tests/freeze/secure/unprotectedA.dhall view
@@ -0,0 +1,1 @@+./True.dhall
+ tests/freeze/secure/unprotectedB.dhall view
@@ -0,0 +1,2 @@+./True.dhall+  sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70
− tests/freeze/unprotectedA.dhall
@@ -1,1 +0,0 @@-./True.dhall
− tests/freeze/unprotectedB.dhall
@@ -1,2 +0,0 @@-  ./True.dhall sha256:27abdeddfe8503496adeb623466caa47da5f63abd2bc6fa19f6cfcb73ecfed70-? ./True.dhall
+ tests/package/dir/package.dhall view
+ tests/package/dir/subdirectory1/test.dhall view
+ tests/package/dir/subdirectory2/wrong-extension.txt view
+ tests/package/dir/test.dhall view
+ tests/package/dir/wrong-extension.txt view
+ tests/package/empty/wrong-extension.txt view
+ tests/package/other/package.dhall view
+ tests/package/package.dhall view
+ tests/package/test.dhall view
+ tests/package/test/test.dhall view
+ tests/regression/issue2088.dhall view
@@ -0,0 +1,1 @@+[ { x = 1 }.{ x }, { x = 1 } ]
+ tests/th/HigherKindSingle.dhall view
@@ -0,0 +1,1 @@+\(a : Type -> Type) -> \(a : Type) -> { foo : a, bar : a@1 a, bam : Text }
+ tests/th/HigherKindUnion.dhall view
@@ -0,0 +1,1 @@+\(a : Type) -> \(b : Type) -> < Foo : a | Bar : b >
+ tests/th/Time.dhall view
@@ -0,0 +1,1 @@+{ txTime : Time, txDate : Date, txTimeZone : TimeZone }
+ tests/to-directory-tree/fixpoint-allow-path-separators.dhall view
@@ -0,0 +1,25 @@+let User = (./fixpoint-helper.dhall).User++let Group = (./fixpoint-helper.dhall).Group++let Mode = (./fixpoint-helper.dhall).Mode++let Make = (./fixpoint-helper.dhall).Make++in  \(r : Type) ->+    \(make : Make r) ->+      [ make.file+          { name = "non-existent-1/file"+          , content = ""+          , user = None User+          , group = None Group+          , mode = None Mode+          }+      , make.directory+          { name = "non-existent-2/directory"+          , content = [] : List r+          , user = None User+          , group = None Group+          , mode = None Mode+          }+      ]
+ tests/to-directory-tree/fixpoint-empty.dhall view
@@ -0,0 +1,3 @@+let Make = (./fixpoint-helper.dhall).Make++in  \(r : Type) -> \(make : Make r) -> [] : List r
+ tests/to-directory-tree/fixpoint-helper.dhall view
@@ -0,0 +1,30 @@+let User = < UserId : Natural | UserName : Text >++let Group = < GroupId : Natural | GroupName : Text >++let Access =+      { execute : Optional Bool, read : Optional Bool, write : Optional Bool }++let Mode =+      { user : Optional Access+      , group : Optional Access+      , other : Optional Access+      }++let Entry =+      \(content : Type) ->+        { name : Text+        , content : content+        , user : Optional User+        , group : Optional Group+        , mode : Optional Mode+        }++let Make =+      \(r : Type) ->+        { directory : Entry (List r) -> r+        , binary-file : Entry Bytes -> r+        , file : Entry Text -> r+        }++in  { User, Group, Access, Mode, Entry, Make }
+ tests/to-directory-tree/fixpoint-permissions.dhall view
@@ -0,0 +1,24 @@+let User = (./fixpoint-helper.dhall).User++let Group = (./fixpoint-helper.dhall).Group++let Make = (./fixpoint-helper.dhall).Make++let no-access = { execute = Some False, read = Some False, write = Some False }++let full-access = { execute = Some True, read = Some True, write = Some True }++in  \(r : Type) ->+    \(make : Make r) ->+      [ make.file+          { name = "file"+          , content = ""+          , user = None User+          , group = None Group+          , mode = Some+            { user = Some full-access+            , group = Some no-access+            , other = Some no-access+            }+          }+      ]
+ tests/to-directory-tree/fixpoint-simple.dhall view
@@ -0,0 +1,25 @@+let User = (./fixpoint-helper.dhall).User++let Group = (./fixpoint-helper.dhall).Group++let Mode = (./fixpoint-helper.dhall).Mode++let Make = (./fixpoint-helper.dhall).Make++in  \(r : Type) ->+    \(make : Make r) ->+      [ make.file+          { name = "file"+          , content = ""+          , user = None User+          , group = None Group+          , mode = None Mode+          }+      , make.directory+          { name = "directory"+          , content = [] : List r+          , user = None User+          , group = None Group+          , mode = None Mode+          }+      ]
+ tests/to-directory-tree/fixpoint-usergroup.dhall view
@@ -0,0 +1,25 @@+let User = (./fixpoint-helper.dhall).User++let Group = (./fixpoint-helper.dhall).Group++let Mode = (./fixpoint-helper.dhall).Mode++let Make = (./fixpoint-helper.dhall).Make++in  \(r : Type) ->+    \(make : Make r) ->+      [ make.file+          { name = "ids"+          , content = ""+          , user = Some (User.UserId 0)+          , group = Some (Group.GroupId 0)+          , mode = None Mode+          }+      , make.file+          { name = "names"+          , content = ""+          , user = Some (User.UserName "user")+          , group = Some (Group.GroupName "group")+          , mode = None Mode+          }+      ]
+ tests/to-directory-tree/type.dhall view
@@ -0,0 +1,36 @@+let User = < UserId : Natural | UserName : Text >++let Group = < GroupId : Natural | GroupName : Text >++let Access =+      { execute : Optional Bool, read : Optional Bool, write : Optional Bool }++let Mode =+      { user : Optional Access+      , group : Optional Access+      , other : Optional Access+      }++let Entry =+      \(content : Type) ->+        { name : Text+        , content : content+        , user : Optional User+        , group : Optional Group+        , mode : Optional Mode+        }++in  forall (result : Type) ->+      let DirectoryEntry = Entry (List result)++      let BinaryFileEntry = Entry Bytes++      let TextFileEntry = Entry Text++      let Make =+            { directory : DirectoryEntry -> result+            , binary-file : BinaryFileEntry -> result+            , file : TextFileEntry -> result+            }++      in  forall (make : Make) -> List result