packages feed

dhall 1.27.0 → 1.28.0

raw patch · 163 files changed

+5900/−3533 lines, 163 filesdep +atomic-writedep +pretty-simpledep ~hashabledep ~megaparsecdep ~prettyprinterbinary-addedPVP ok

version bump matches the API change (PVP)

Dependencies added: atomic-write, pretty-simple

Dependency ranges changed: hashable, megaparsec, prettyprinter

API changes (from Hackage documentation)

- Dhall: InputType :: (a -> Expr Src Void) -> Expr Src Void -> InputType a
- Dhall: InvalidType :: Expr s a -> Expr s a -> InvalidType s a
- Dhall: RecordInputType :: Map Text (InputType a) -> RecordInputType a
- Dhall: RecordType :: Product (Const (Map Text (Expr Src Void))) (Compose ((->) (Expr Src Void)) (Extractor Src Void)) a -> RecordType a
- Dhall: Type :: (Expr Src Void -> Extractor Src Void a) -> Expr Src Void -> Type a
- Dhall: UnionInputType :: Product (Const (Map Text (Expr Src Void))) (Op (Text, Expr Src Void)) a -> UnionInputType a
- Dhall: UnionType :: Compose (Map Text) Type a -> UnionType a
- Dhall: [invalidTypeExpected] :: InvalidType s a -> Expr s a
- Dhall: [invalidTypeExpression] :: InvalidType s a -> Expr s a
- Dhall: data InputType a
- Dhall: data InvalidType s a
- Dhall: data Type a
- Dhall: inputConstructor :: ToDhall a => Text -> UnionInputType a
- Dhall: inputConstructorWith :: Text -> InputType a -> UnionInputType a
- Dhall: inputField :: ToDhall a => Text -> RecordInputType a
- Dhall: inputFieldWith :: Text -> InputType a -> RecordInputType a
- Dhall: inputRecord :: RecordInputType a -> InputType a
- Dhall: inputUnion :: UnionInputType a -> InputType a
- Dhall: instance (Data.Text.Prettyprint.Doc.Internal.Pretty s, Data.Text.Prettyprint.Doc.Internal.Pretty a, Data.Typeable.Internal.Typeable s, Data.Typeable.Internal.Typeable a) => GHC.Show.Show (Dhall.InvalidType s a)
- Dhall: instance (Data.Text.Prettyprint.Doc.Internal.Pretty s, Data.Typeable.Internal.Typeable s, Data.Text.Prettyprint.Doc.Internal.Pretty a, Data.Typeable.Internal.Typeable a) => GHC.Exception.Type.Exception (Dhall.InvalidType s a)
- Dhall: instance Data.Functor.Contravariant.Contravariant Dhall.InputType
- Dhall: instance Data.Functor.Contravariant.Contravariant Dhall.RecordInputType
- Dhall: instance Data.Functor.Contravariant.Contravariant Dhall.UnionInputType
- Dhall: instance Data.Functor.Contravariant.Divisible.Divisible Dhall.RecordInputType
- Dhall: instance GHC.Base.Applicative Dhall.RecordType
- Dhall: instance GHC.Base.Functor Dhall.RecordType
- Dhall: instance GHC.Base.Functor Dhall.Type
- Dhall: instance GHC.Base.Functor Dhall.UnionType
- Dhall: instance GHC.Base.Monoid (Dhall.UnionType a)
- Dhall: instance GHC.Base.Semigroup (Dhall.UnionType a)
- Dhall: newtype RecordInputType a
- Dhall: newtype RecordType a
- Dhall: newtype UnionInputType a
- Dhall: newtype UnionType a
- Dhall.Binary: class FromTerm a
- Dhall.Binary: class ToTerm a
- Dhall.Binary: data DecodingFailure
- Dhall.Binary: decode :: FromTerm a => Term -> Maybe a
- Dhall.Binary: encode :: ToTerm a => a -> Term
- Dhall.Binary: instance Dhall.Binary.FromTerm Data.Void.Void
- Dhall.Binary: instance Dhall.Binary.FromTerm Dhall.Syntax.Import
- Dhall.Binary: instance Dhall.Binary.FromTerm a => Dhall.Binary.FromTerm (Dhall.Syntax.Expr s a)
- Dhall.Binary: instance Dhall.Binary.ToTerm Data.Void.Void
- Dhall.Binary: instance Dhall.Binary.ToTerm Dhall.Syntax.DhallDouble
- Dhall.Binary: instance Dhall.Binary.ToTerm Dhall.Syntax.Import
- Dhall.Binary: instance Dhall.Binary.ToTerm a => Dhall.Binary.ToTerm (Dhall.Syntax.Expr Data.Void.Void a)
- Dhall.Parser.Token: _colonOnly :: Parser ()
- Dhall.Parser.Token: _equalOnly :: Parser ()
- Dhall.Parser.Token: _letOnly :: Parser ()
- Dhall.Parser.Token: labelOnly :: Parser Text
- Dhall.TypeCheck: instance (GHC.Classes.Eq a, Data.Text.Prettyprint.Doc.Internal.Pretty s, Data.Text.Prettyprint.Doc.Internal.Pretty a, Dhall.Binary.ToTerm a) => Data.Text.Prettyprint.Doc.Internal.Pretty (Dhall.TypeCheck.DetailedTypeError s a)
- Dhall.TypeCheck: instance (GHC.Classes.Eq a, Data.Text.Prettyprint.Doc.Internal.Pretty s, Data.Text.Prettyprint.Doc.Internal.Pretty a, Dhall.Binary.ToTerm a) => Data.Text.Prettyprint.Doc.Internal.Pretty (Dhall.TypeCheck.TypeError s a)
- Dhall.TypeCheck: instance (GHC.Classes.Eq a, Data.Text.Prettyprint.Doc.Internal.Pretty s, Data.Text.Prettyprint.Doc.Internal.Pretty a, Dhall.Binary.ToTerm a) => GHC.Show.Show (Dhall.TypeCheck.DetailedTypeError s a)
- Dhall.TypeCheck: instance (GHC.Classes.Eq a, Data.Text.Prettyprint.Doc.Internal.Pretty s, Data.Text.Prettyprint.Doc.Internal.Pretty a, Dhall.Binary.ToTerm a) => GHC.Show.Show (Dhall.TypeCheck.TypeError s a)
- Dhall.TypeCheck: instance (GHC.Classes.Eq a, Data.Text.Prettyprint.Doc.Internal.Pretty s, Data.Text.Prettyprint.Doc.Internal.Pretty a, Dhall.Binary.ToTerm a, Data.Typeable.Internal.Typeable s, Data.Typeable.Internal.Typeable a) => GHC.Exception.Type.Exception (Dhall.TypeCheck.DetailedTypeError s a)
- Dhall.TypeCheck: instance (GHC.Classes.Eq a, Data.Text.Prettyprint.Doc.Internal.Pretty s, Data.Text.Prettyprint.Doc.Internal.Pretty a, Dhall.Binary.ToTerm a, Data.Typeable.Internal.Typeable s, Data.Typeable.Internal.Typeable a) => GHC.Exception.Type.Exception (Dhall.TypeCheck.TypeError s a)
+ Dhall: Decoder :: (Expr Src Void -> Extractor Src Void a) -> Expr Src Void -> Decoder a
+ Dhall: Encoder :: (a -> Expr Src Void) -> Expr Src Void -> Encoder a
+ Dhall: InvalidDecoder :: Expr s a -> Expr s a -> InvalidDecoder s a
+ Dhall: RecordDecoder :: Product (Const (Map Text (Expr Src Void))) (Compose ((->) (Expr Src Void)) (Extractor Src Void)) a -> RecordDecoder a
+ Dhall: RecordEncoder :: Map Text (Encoder a) -> RecordEncoder a
+ Dhall: UnionDecoder :: Compose (Map Text) Decoder a -> UnionDecoder a
+ Dhall: UnionEncoder :: Product (Const (Map Text (Expr Src Void))) (Op (Text, Expr Src Void)) a -> UnionEncoder a
+ Dhall: [invalidDecoderExpected] :: InvalidDecoder s a -> Expr s a
+ Dhall: [invalidDecoderExpression] :: InvalidDecoder s a -> Expr s a
+ Dhall: data Decoder a
+ Dhall: data Encoder a
+ Dhall: data InvalidDecoder s a
+ Dhall: encodeConstructor :: ToDhall a => Text -> UnionEncoder a
+ Dhall: encodeConstructorWith :: Text -> Encoder a -> UnionEncoder a
+ Dhall: encodeField :: ToDhall a => Text -> RecordEncoder a
+ Dhall: encodeFieldWith :: Text -> Encoder a -> RecordEncoder a
+ Dhall: function :: InterpretOptions -> Encoder a -> Decoder b -> Decoder (a -> b)
+ Dhall: instance (Data.Text.Prettyprint.Doc.Internal.Pretty s, Data.Text.Prettyprint.Doc.Internal.Pretty a, Data.Typeable.Internal.Typeable s, Data.Typeable.Internal.Typeable a) => GHC.Show.Show (Dhall.InvalidDecoder s a)
+ Dhall: instance (Data.Text.Prettyprint.Doc.Internal.Pretty s, Data.Typeable.Internal.Typeable s, Data.Text.Prettyprint.Doc.Internal.Pretty a, Data.Typeable.Internal.Typeable a) => GHC.Exception.Type.Exception (Dhall.InvalidDecoder s a)
+ Dhall: instance Data.Functor.Contravariant.Contravariant Dhall.Encoder
+ Dhall: instance Data.Functor.Contravariant.Contravariant Dhall.RecordEncoder
+ Dhall: instance Data.Functor.Contravariant.Contravariant Dhall.UnionEncoder
+ Dhall: instance Data.Functor.Contravariant.Divisible.Divisible Dhall.RecordEncoder
+ Dhall: instance GHC.Base.Applicative Dhall.RecordDecoder
+ Dhall: instance GHC.Base.Functor Dhall.Decoder
+ Dhall: instance GHC.Base.Functor Dhall.RecordDecoder
+ Dhall: instance GHC.Base.Functor Dhall.UnionDecoder
+ Dhall: instance GHC.Base.Monoid (Dhall.UnionDecoder a)
+ Dhall: instance GHC.Base.Semigroup (Dhall.UnionDecoder a)
+ Dhall: newtype RecordDecoder a
+ Dhall: newtype RecordEncoder a
+ Dhall: newtype UnionDecoder a
+ Dhall: newtype UnionEncoder a
+ Dhall: recordEncoder :: RecordEncoder a -> Encoder a
+ Dhall: unionEncoder :: UnionEncoder a -> Encoder a
+ Dhall.Binary: instance Codec.Serialise.Class.Serialise (Dhall.Syntax.Expr Data.Void.Void Data.Void.Void)
+ Dhall.Binary: instance Codec.Serialise.Class.Serialise (Dhall.Syntax.Expr Data.Void.Void Dhall.Syntax.Import)
+ Dhall.Binary: newtype DecodingFailure
+ Dhall.Core: IntegerClamp :: Expr s a
+ Dhall.Core: IntegerNegate :: Expr s a
+ Dhall.Import: [_manager] :: Status -> Maybe Manager
+ Dhall.Lint: fixAssert :: Expr s a -> Maybe (Expr s a)
+ Dhall.Lint: fixParentPath :: Expr s Import -> Maybe (Expr s Import)
+ Dhall.Main: SyntaxTree :: Input -> Mode
+ Dhall.Map: empty :: Ord k => Map k v
+ Dhall.Map: toAscList :: Map k v -> [(k, v)]
+ Dhall.Map: withoutKeys :: Ord k => Map k a -> Set k -> Map k a
+ Dhall.Parser: Header :: Text -> Header
+ Dhall.Parser: createHeader :: Text -> Header
+ Dhall.Parser: instance GHC.Show.Show Dhall.Parser.Header
+ Dhall.Parser: newtype Header
+ Dhall.Parser.Token: _IntegerClamp :: Parser ()
+ Dhall.Parser.Token: _IntegerNegate :: Parser ()
+ Dhall.Parser.Token: char :: Char -> Parser Char
+ Dhall.Parser.Token: text :: Text -> Parser Text
+ Dhall.Pretty: layout :: Doc ann -> SimpleDocStream ann
+ Dhall.Set: size :: Set a -> Int
+ Dhall.Set: toAscList :: Set a -> [a]
+ Dhall.TypeCheck: CompletionSchemaMustBeARecord :: Expr s a -> Expr s a -> TypeMessage s a
+ Dhall.TypeCheck: InvalidRecordCompletion :: Text -> Expr s a -> TypeMessage s a
+ Dhall.TypeCheck: instance (GHC.Classes.Eq a, Data.Text.Prettyprint.Doc.Internal.Pretty s, Data.Text.Prettyprint.Doc.Internal.Pretty a) => Data.Text.Prettyprint.Doc.Internal.Pretty (Dhall.TypeCheck.DetailedTypeError s a)
+ Dhall.TypeCheck: instance (GHC.Classes.Eq a, Data.Text.Prettyprint.Doc.Internal.Pretty s, Data.Text.Prettyprint.Doc.Internal.Pretty a) => Data.Text.Prettyprint.Doc.Internal.Pretty (Dhall.TypeCheck.TypeError s a)
+ Dhall.TypeCheck: instance (GHC.Classes.Eq a, Data.Text.Prettyprint.Doc.Internal.Pretty s, Data.Text.Prettyprint.Doc.Internal.Pretty a) => GHC.Show.Show (Dhall.TypeCheck.DetailedTypeError s a)
+ Dhall.TypeCheck: instance (GHC.Classes.Eq a, Data.Text.Prettyprint.Doc.Internal.Pretty s, Data.Text.Prettyprint.Doc.Internal.Pretty a) => GHC.Show.Show (Dhall.TypeCheck.TypeError s a)
+ Dhall.TypeCheck: instance (GHC.Classes.Eq a, Data.Text.Prettyprint.Doc.Internal.Pretty s, Data.Text.Prettyprint.Doc.Internal.Pretty a, Data.Typeable.Internal.Typeable s, Data.Typeable.Internal.Typeable a) => GHC.Exception.Type.Exception (Dhall.TypeCheck.DetailedTypeError s a)
+ Dhall.TypeCheck: instance (GHC.Classes.Eq a, Data.Text.Prettyprint.Doc.Internal.Pretty s, Data.Text.Prettyprint.Doc.Internal.Pretty a, Data.Typeable.Internal.Typeable s, Data.Typeable.Internal.Typeable a) => GHC.Exception.Type.Exception (Dhall.TypeCheck.TypeError s a)
+ Dhall.Util: Header :: Text -> Header
+ Dhall.Util: getExpressionAndHeaderFromStdinText :: Censor -> Text -> IO (Header, Expr Src Import)
+ Dhall.Util: newtype Header
- Dhall: (>|<) :: UnionInputType a -> UnionInputType b -> UnionInputType (Either a b)
+ Dhall: (>|<) :: UnionEncoder a -> UnionEncoder b -> UnionEncoder (Either a b)
- Dhall: [declared] :: InputType a -> Expr Src Void
+ Dhall: [declared] :: Encoder a -> Expr Src Void
- Dhall: [embed] :: InputType a -> a -> Expr Src Void
+ Dhall: [embed] :: Encoder a -> a -> Expr Src Void
- Dhall: [expected] :: Type a -> Expr Src Void
+ Dhall: [expected] :: Decoder a -> Expr Src Void
- Dhall: [extract] :: Type a -> Expr Src Void -> Extractor Src Void a
+ Dhall: [extract] :: Decoder a -> Expr Src Void -> Extractor Src Void a
- Dhall: auto :: FromDhall a => Type a
+ Dhall: auto :: FromDhall a => Decoder a
- Dhall: autoWith :: (FromDhall a, Generic a, GenericFromDhall (Rep a)) => InterpretOptions -> Type a
+ Dhall: autoWith :: (FromDhall a, Generic a, GenericFromDhall (Rep a)) => InterpretOptions -> Decoder a
- Dhall: bool :: Type Bool
+ Dhall: bool :: Decoder Bool
- Dhall: constructor :: Text -> Type a -> UnionType a
+ Dhall: constructor :: Text -> Decoder a -> UnionDecoder a
- Dhall: double :: Type Double
+ Dhall: double :: Decoder Double
- Dhall: field :: Text -> Type a -> RecordType a
+ Dhall: field :: Text -> Decoder a -> RecordDecoder a
- Dhall: genericAuto :: (Generic a, GenericFromDhall (Rep a)) => Type a
+ Dhall: genericAuto :: (Generic a, GenericFromDhall (Rep a)) => Decoder a
- Dhall: genericAutoWith :: GenericFromDhall f => InterpretOptions -> State Int (Type (f a))
+ Dhall: genericAutoWith :: GenericFromDhall f => InterpretOptions -> State Int (Decoder (f a))
- Dhall: genericToDhall :: (Generic a, GenericToDhall (Rep a)) => InputType a
+ Dhall: genericToDhall :: (Generic a, GenericToDhall (Rep a)) => Encoder a
- Dhall: genericToDhallWith :: GenericToDhall f => InterpretOptions -> State Int (InputType (f a))
+ Dhall: genericToDhallWith :: GenericToDhall f => InterpretOptions -> State Int (Encoder (f a))
- Dhall: hashMap :: (Eq k, Hashable k) => Type k -> Type v -> Type (HashMap k v)
+ Dhall: hashMap :: (Eq k, Hashable k) => Decoder k -> Decoder v -> Decoder (HashMap k v)
- Dhall: hashSetFromDistinctList :: (Hashable a, Ord a, Show a) => Type a -> Type (HashSet a)
+ Dhall: hashSetFromDistinctList :: (Hashable a, Ord a, Show a) => Decoder a -> Decoder (HashSet a)
- Dhall: hashSetIgnoringDuplicates :: (Hashable a, Ord a) => Type a -> Type (HashSet a)
+ Dhall: hashSetIgnoringDuplicates :: (Hashable a, Ord a) => Decoder a -> Decoder (HashSet a)
- Dhall: inject :: ToDhall a => InputType a
+ Dhall: inject :: ToDhall a => Encoder a
- Dhall: injectWith :: (ToDhall a, Generic a, GenericToDhall (Rep a)) => InterpretOptions -> InputType a
+ Dhall: injectWith :: (ToDhall a, Generic a, GenericToDhall (Rep a)) => InterpretOptions -> Encoder a
- Dhall: input :: Type a -> Text -> IO a
+ Dhall: input :: Decoder a -> Text -> IO a
- Dhall: inputFile :: Type a -> FilePath -> IO a
+ Dhall: inputFile :: Decoder a -> FilePath -> IO a
- Dhall: inputFileWithSettings :: EvaluateSettings -> Type a -> FilePath -> IO a
+ Dhall: inputFileWithSettings :: EvaluateSettings -> Decoder a -> FilePath -> IO a
- Dhall: inputWithSettings :: InputSettings -> Type a -> Text -> IO a
+ Dhall: inputWithSettings :: InputSettings -> Decoder a -> Text -> IO a
- Dhall: integer :: Type Integer
+ Dhall: integer :: Decoder Integer
- Dhall: lazyText :: Type Text
+ Dhall: lazyText :: Decoder Text
- Dhall: list :: Type a -> Type [a]
+ Dhall: list :: Decoder a -> Decoder [a]
- Dhall: map :: Ord k => Type k -> Type v -> Type (Map k v)
+ Dhall: map :: Ord k => Decoder k -> Decoder v -> Decoder (Map k v)
- Dhall: maybe :: Type a -> Type (Maybe a)
+ Dhall: maybe :: Decoder a -> Decoder (Maybe a)
- Dhall: natural :: Type Natural
+ Dhall: natural :: Decoder Natural
- Dhall: pair :: Type a -> Type b -> Type (a, b)
+ Dhall: pair :: Decoder a -> Decoder b -> Decoder (a, b)
- Dhall: pairFromMapEntry :: Type k -> Type v -> Type (k, v)
+ Dhall: pairFromMapEntry :: Decoder k -> Decoder v -> Decoder (k, v)
- Dhall: rawInput :: Alternative f => Type a -> Expr s Void -> f a
+ Dhall: rawInput :: Alternative f => Decoder a -> Expr s Void -> f a
- Dhall: record :: RecordType a -> Type a
+ Dhall: record :: RecordDecoder a -> Decoder a
- Dhall: scientific :: Type Scientific
+ Dhall: scientific :: Decoder Scientific
- Dhall: sequence :: Type a -> Type (Seq a)
+ Dhall: sequence :: Decoder a -> Decoder (Seq a)
- Dhall: setFromDistinctList :: (Ord a, Show a) => Type a -> Type (Set a)
+ Dhall: setFromDistinctList :: (Ord a, Show a) => Decoder a -> Decoder (Set a)
- Dhall: setIgnoringDuplicates :: Ord a => Type a -> Type (Set a)
+ Dhall: setIgnoringDuplicates :: Ord a => Decoder a -> Decoder (Set a)
- Dhall: strictText :: Type Text
+ Dhall: strictText :: Decoder Text
- Dhall: string :: Type String
+ Dhall: string :: Decoder String
- Dhall: union :: UnionType a -> Type a
+ Dhall: union :: UnionDecoder a -> Decoder a
- Dhall: unit :: Type ()
+ Dhall: unit :: Decoder ()
- Dhall: vector :: Type a -> Type (Vector a)
+ Dhall: vector :: Decoder a -> Decoder (Vector a)
- Dhall: void :: Type Void
+ Dhall: void :: Decoder Void
- Dhall.Binary: CBORIsNotDhall :: Term -> DecodingFailure
+ Dhall.Binary: CBORIsNotDhall :: ByteString -> DecodingFailure
- Dhall.Binary: decodeExpression :: FromTerm a => Term -> Either DecodingFailure (Expr s a)
+ Dhall.Binary: decodeExpression :: Serialise (Expr s a) => ByteString -> Either DecodingFailure (Expr s a)
- Dhall.Binary: encodeExpression :: Expr s Import -> Term
+ Dhall.Binary: encodeExpression :: Expr Void Import -> ByteString
- Dhall.Diff: diffNormalized :: (Eq a, Pretty a, ToTerm a) => Expr s a -> Expr s a -> Diff
+ Dhall.Diff: diffNormalized :: (Eq a, Pretty a) => Expr s a -> Expr s a -> Diff
- Dhall.Import: Status :: NonEmpty Chained -> [Depends] -> Map Chained ImportSemantics -> (URL -> StateT Status IO Text) -> Maybe (ReifiedNormalizer Void) -> Context (Expr Src Void) -> SemanticCacheMode -> Status
+ Dhall.Import: Status :: NonEmpty Chained -> [Depends] -> Map Chained ImportSemantics -> Maybe Manager -> (URL -> StateT Status IO Text) -> Maybe (ReifiedNormalizer Void) -> Context (Expr Src Void) -> SemanticCacheMode -> Status
- Dhall.Import: hashExpression :: Expr s Void -> SHA256Digest
+ Dhall.Import: hashExpression :: Expr Void Void -> SHA256Digest
- Dhall.Import: hashExpressionToCode :: Expr s Void -> Text
+ Dhall.Import: hashExpressionToCode :: Expr Void Void -> Text
- Dhall.Import: writeExpressionToSemanticCache :: Expr Src Void -> IO ()
+ Dhall.Import: writeExpressionToSemanticCache :: Expr Void Void -> IO ()
- Dhall.Parser: exprAndHeaderFromText :: String -> Text -> Either ParseError (Text, Expr Src Import)
+ Dhall.Parser: exprAndHeaderFromText :: String -> Text -> Either ParseError (Header, Expr Src Import)
- Dhall.Parser.Token: validCodepoint :: Char -> Bool
+ Dhall.Parser.Token: validCodepoint :: Int -> Bool
- Dhall.TypeCheck: MissingHandler :: Set Text -> TypeMessage s a
+ Dhall.TypeCheck: MissingHandler :: Text -> Set Text -> TypeMessage s a
- Dhall.Util: getExpressionAndHeader :: Censor -> Input -> IO (Text, Expr Src Import)
+ Dhall.Util: getExpressionAndHeader :: Censor -> Input -> IO (Header, Expr Src Import)

Files

CHANGELOG.md view
@@ -1,3 +1,89 @@+1.28.0++* [Supports version 12.0.0 of the standard](https://github.com/dhall-lang/dhall-lang/releases/tag/v12.0.0)+* BREAKING CHANGE: [Add `Integer/{clamp,negate}` built-ins](https://github.com/dhall-lang/dhall-haskell/pull/1486)+    * This is a technically breaking change API since this adds a new+      constructor to the `Expr` type+    * This is also a technically breaking change to the language.  See the [changelog for standard version 12.0.0](https://github.com/dhall-lang/dhall-lang/releases/tag/v12.0.0) for more details+* BREAKING CHANGE: [Remove support for fusion](https://github.com/dhall-lang/dhall-haskell/pull/1478)+    * This is also a technically breaking change to the language.  See the [changelog for standard version 12.0.0](https://github.com/dhall-lang/dhall-lang/releases/tag/v12.0.0) for more details+* BREAKING CHANGE: [Parse whitespace more precisely](https://github.com/dhall-lang/dhall-haskell/pull/1483)+    * The Haskell implementation now matches the official grammar much more+      closely, but as a result will now reject some programs that it used to+      accept+    * For example, `1:Natural` used to be valid and now is no longer valid as+      the standard requires mandatory whitespace after the `:`+    * Consult the [standard grammar](https://github.com/dhall-lang/dhall-lang/blob/master/standard/dhall.abnf) if you run into a new parsing error as a result of this change+    * This is also a parsing performance regression (specifically for parsing+      comments), but should not be noticeable in practice.  See [#1512](https://github.com/dhall-lang/dhall-haskell/pull/1512) for more details+* BREAKING CHANGE: Rename `Type` to `Decoder` and `InputType` to `Encoder` [#1483](https://github.com/dhall-lang/dhall-haskell/pull/1485) / [#1489](https://github.com/dhall-lang/dhall-haskell/pull/1489)+* BUG FIX: [Fix `dhall format --check`](https://github.com/dhall-lang/dhall-haskell/pull/1462)+    * Before this change `dhall format --check` would fail due to attempting to+      read all of standard input in twice+* BUG FIX: [Fix `dhall freeze` to always re-freeze an import](https://github.com/dhall-lang/dhall-haskell/pull/1471)+    * Before this fix, `dhall freeze` would not attempt to refreeze an already+      frozen import+* [Permit spaces around completion operator](https://github.com/dhall-lang/dhall-haskell/pull/1532)+    * See the [changelog for standard version 12.0.0](https://github.com/dhall-lang/dhall-lang/releases/tag/v12.0.0) for more details+* [Make `missing` referentially transparent](https://github.com/dhall-lang/dhall-haskell/pull/1509)+    * `missing` can now be imported transitively via a remote import+    * Normally resolving `missing` would still still fail, except for+      `missing as Location`, which is now a valid transitive import+    * See the [changelog for standard version 12.0.0](https://github.com/dhall-lang/dhall-lang/releases/tag/v12.0.0) for more details+* [Write cache files atomically](https://github.com/dhall-lang/dhall-haskell/pull/1544)+    * This is a resilience improvement so that the cache is not left in a+      corrupt state in the event of a power outage or exhausting disk/memory+* [New `Dhall.function` utility](https://github.com/dhall-lang/dhall-haskell/pull/1507)+    * This is provides the same functionality as the `Interpret` instance for+      `(->)`, except without the use of typeclasses+* [New `dhall haskell-syntax-tree` command](https://github.com/dhall-lang/dhall-haskell/pull/1553)+    * This command displays the Haskell syntax tree of an expression+      (primarily for debugging purposes)+    * Note that this is highly-volatile and subject to change, so don't depend+      on this programmatically.  We may break the output of this command without+      any notice.+* [Add `instance Show Ann`](https://github.com/dhall-lang/dhall-haskell/pull/1567)+* [Move normalization code from `Dhall.Core` to `Dhall.Normalize`](https://github.com/dhall-lang/dhall-haskell/pull/1452)+    * Note that this is not a breaking change.  The relocated utilities are+      still re-exported from `Dhall.Core`+* [Fix `dhall resolve --transitive-dependencies` to list dependencies in "post-order"](https://github.com/dhall-lang/dhall-haskell/pull/1539)+* Performance improvements+    * [#1500](https://github.com/dhall-lang/dhall-haskell/pull/1500)+    * [#1522](https://github.com/dhall-lang/dhall-haskell/pull/1522)+    * [#1568](https://github.com/dhall-lang/dhall-haskell/pull/1568)+    * [#1580](https://github.com/dhall-lang/dhall-haskell/pull/1578)+* Fixes and improvements to code formatting+    * [#1460](https://github.com/dhall-lang/dhall-haskell/pull/1460)+    * [#1466](https://github.com/dhall-lang/dhall-haskell/pull/1466)+    * [#1508](https://github.com/dhall-lang/dhall-haskell/pull/1508)+    * [#1527](https://github.com/dhall-lang/dhall-haskell/pull/1527)+    * [#1422](https://github.com/dhall-lang/dhall-haskell/pull/1422)+    * [#1552](https://github.com/dhall-lang/dhall-haskell/pull/1552)+    * [#1543](https://github.com/dhall-lang/dhall-haskell/pull/1543)+    * [#1554](https://github.com/dhall-lang/dhall-haskell/pull/1554)+    * [#1569](https://github.com/dhall-lang/dhall-haskell/pull/1569)+* Fixes and improvements to code linting+    * [#1518](https://github.com/dhall-lang/dhall-haskell/pull/1518)+    * [#1531](https://github.com/dhall-lang/dhall-haskell/pull/1531)+* Fixes and improvements to error messages+    * [#1443](https://github.com/dhall-lang/dhall-haskell/pull/1443)+    * [#1448](https://github.com/dhall-lang/dhall-haskell/pull/1448)+    * [#1482](https://github.com/dhall-lang/dhall-haskell/pull/1482)+    * [#1519](https://github.com/dhall-lang/dhall-haskell/pull/1519)+    * [#1556](https://github.com/dhall-lang/dhall-haskell/pull/1556)+    * [#1528](https://github.com/dhall-lang/dhall-haskell/pull/1528)+* Fixes and improvements to the parser+    * [#1473](https://github.com/dhall-lang/dhall-haskell/pull/1473)+    * [#1549](https://github.com/dhall-lang/dhall-haskell/pull/1549)+    * [#1563](https://github.com/dhall-lang/dhall-haskell/pull/1563)+    * [#1584](https://github.com/dhall-lang/dhall-haskell/pull/1584)+* Fixes and improvements to diffs+    * [#1585](https://github.com/dhall-lang/dhall-haskell/pull/1585)+* Fixes and improvements to the REPL+    * [#1573](https://github.com/dhall-lang/dhall-haskell/pull/1573)+* Fixes and improvements to documentation+    * [#1530](https://github.com/dhall-lang/dhall-haskell/pull/1530)+ 1.27.0  * [Supports version 11.0.0 of the standard](https://github.com/dhall-lang/dhall-lang/releases/tag/v11.0.0)
benchmark/parser/Main.hs view
@@ -6,7 +6,8 @@ import Control.Monad (forM) import Data.Map (Map, foldrWithKey, singleton, unions) import Data.Monoid ((<>))-import Gauge (defaultMain, bgroup, bench, whnf, nfIO)+import Data.Void (Void)+import Gauge (defaultMain, bgroup, bench, nf, whnf, nfIO)  import System.Directory @@ -67,27 +68,25 @@  benchExprFromBytes     :: String -> Data.ByteString.Lazy.ByteString -> Gauge.Benchmark-benchExprFromBytes name bytes = bench name (whnf f bytes)+benchExprFromBytes name bytes = bench name (nf f bytes)   where     f bytes = do-        term <- case Codec.Serialise.deserialiseOrFail bytes of-            Left  _    -> Nothing-            Right term -> return term-        case Dhall.Binary.decodeExpression term-          :: Either Dhall.Binary.DecodingFailure (Dhall.Expr () Dhall.Import) of-            Left  _          -> Nothing-            Right expression -> return expression+        case Dhall.Binary.decodeExpression bytes of+            Left  exception  -> error (show exception)+            Right expression -> expression :: Dhall.Expr Void Dhall.Import  main :: IO () main = do     prelude <- loadPreludeFiles     issue108Text  <- TIO.readFile "benchmark/examples/issue108.dhall"     issue108Bytes <- Data.ByteString.Lazy.readFile "benchmark/examples/issue108.dhall.bin"+    kubernetesExample <- Data.ByteString.Lazy.readFile "benchmark/examples/kubernetes.dhall.bin"     defaultMain         [ bgroup "Issue #108"             [ benchExprFromText  "Text"   issue108Text             , benchExprFromBytes "Binary" issue108Bytes             ]+        , benchExprFromBytes "Kubernetes/Binary" kubernetesExample         , 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" <> "\"")
+ dhall-lang/Prelude/Integer/abs view
@@ -0,0 +1,19 @@+{-+Returns the absolute value of an `Integer`, i.e. its non-negative value.+-}+let abs+    : Integer → Natural+    =   λ(n : Integer)+      →       if Natural/isZero (Integer/clamp n)++        then  Integer/clamp (Integer/negate n)++        else  Integer/clamp n++let example0 = assert : abs +7 ≡ 7++let example2 = assert : abs +0 ≡ 0++let example3 = assert : abs -3 ≡ 3++in  abs
+ dhall-lang/Prelude/Integer/add view
@@ -0,0 +1,26 @@+{-+`add m n` computes `m + n`.+-}+let Integer/subtract =+        ./subtract sha256:8de76d2e235eec1629750ae62e191f13631b36708bfda0425572d87e5a9a37e7+      ? ./subtract++let add+    : Integer → Integer → Integer+    = λ(m : Integer) → λ(n : Integer) → Integer/subtract (Integer/negate m) n++let example0 = assert : add +3 +5 ≡ +8++let example1 = assert : add -3 -5 ≡ -8++let example2 = assert : add -4 +4 ≡ +0++let example3 = assert : add -3 +5 ≡ +2++let example4 = assert : add +3 -5 ≡ -2++let example5 = assert : add +0 -3 ≡ -3++let example6 = assert : add +0 +3 ≡ +3++in  add
+ dhall-lang/Prelude/Integer/clamp view
@@ -0,0 +1,14 @@+{-+Convert an `Integer` to a `Natural` number, with negative numbers becoming zero.+-}+let clamp+    : Integer → Natural+    = Integer/clamp++let example0 = assert : clamp +7 ≡ 7++let example2 = assert : clamp +0 ≡ 0++let example3 = assert : clamp -3 ≡ 0++in  clamp
+ dhall-lang/Prelude/Integer/equal view
@@ -0,0 +1,26 @@+{-+`equal` checks if two Integers are equal.+-}+let greaterThan =+        ./greaterThan sha256:accaa6b7cbca7ec2ace4a529e5f3bb57679df2b5ad962bde5b7867d9253d4b8c+      ? ./greaterThan++let Bool/not =+        ../Bool/not sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4+      ? ../Bool/not++let equal+    : Integer → Integer → Bool+    =   λ(a : Integer)+      → λ(b : Integer)+      → Bool/not (greaterThan a b) && Bool/not (greaterThan b a)++let example0 = assert : equal +5 +5 ≡ True++let example1 = assert : equal +5 +6 ≡ False++let example2 = assert : equal +5 -5 ≡ False++let example3 = assert : equal -5 -5 ≡ True++in  equal
+ dhall-lang/Prelude/Integer/greaterThan view
@@ -0,0 +1,32 @@+{-+`greaterThan` checks if one Integer is greater than another.+-}+let Integer/subtract =+        ./subtract sha256:8de76d2e235eec1629750ae62e191f13631b36708bfda0425572d87e5a9a37e7+      ? ./subtract++let Bool/not =+        ../Bool/not sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4+      ? ../Bool/not++let greaterThan+    : Integer → Integer → Bool+    =   λ(x : Integer)+      → λ(y : Integer)+      → Bool/not (Natural/isZero (Integer/clamp (Integer/subtract y x)))++let example0 = assert : greaterThan +5 +6 ≡ False++let example1 = assert : greaterThan +5 +5 ≡ False++let example2 = assert : greaterThan +5 +4 ≡ True++let example3 = assert : greaterThan -5 +8 ≡ False++let example4 = assert : greaterThan -5 -3 ≡ False++let example5 = assert : greaterThan -3 -5 ≡ True++let example6 = assert : greaterThan -3 -3 ≡ False++in  greaterThan
+ dhall-lang/Prelude/Integer/greaterThanEqual view
@@ -0,0 +1,30 @@+{-+`greaterThanEqual` checks if one Integer is greater than or equal to another.+-}+let greaterThan =+        ./greaterThan sha256:accaa6b7cbca7ec2ace4a529e5f3bb57679df2b5ad962bde5b7867d9253d4b8c+      ? ./greaterThan++let Bool/not =+        ../Bool/not sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4+      ? ../Bool/not++let greaterThanEqual+    : Integer → Integer → Bool+    = λ(x : Integer) → λ(y : Integer) → Bool/not (greaterThan y x)++let example0 = assert : greaterThanEqual +5 +6 ≡ False++let example1 = assert : greaterThanEqual +5 +5 ≡ True++let example2 = assert : greaterThanEqual +5 +4 ≡ True++let example3 = assert : greaterThanEqual -5 +8 ≡ False++let example4 = assert : greaterThanEqual -5 -3 ≡ False++let example5 = assert : greaterThanEqual -3 -5 ≡ True++let example6 = assert : greaterThanEqual -3 -3 ≡ True++in  greaterThanEqual
+ dhall-lang/Prelude/Integer/lessThan view
@@ -0,0 +1,26 @@+{-+`lessThan` checks if one Integer is less than another.+-}+let greaterThan =+        ./greaterThan sha256:accaa6b7cbca7ec2ace4a529e5f3bb57679df2b5ad962bde5b7867d9253d4b8c+      ? ./greaterThan++let lessThan+    : Integer → Integer → Bool+    = λ(x : Integer) → λ(y : Integer) → greaterThan y x++let example0 = assert : lessThan +5 +6 ≡ True++let example1 = assert : lessThan +5 +5 ≡ False++let example2 = assert : lessThan +5 +4 ≡ False++let example3 = assert : lessThan -5 +8 ≡ True++let example4 = assert : lessThan -5 -3 ≡ True++let example5 = assert : lessThan -3 -5 ≡ False++let example6 = assert : lessThan -3 -3 ≡ False++in  lessThan
+ dhall-lang/Prelude/Integer/lessThanEqual view
@@ -0,0 +1,30 @@+{-+`lessThanEqual` checks if one Integer is less than or equal to another.+-}+let lessThan =+        ./lessThan sha256:14cc3bc6ca8757f7c3af338f079fcc18e0c7ee3ed0d20914a9693aec81ae628d+      ? ./lessThan++let Bool/not =+        ../Bool/not sha256:723df402df24377d8a853afed08d9d69a0a6d86e2e5b2bac8960b0d4756c7dc4+      ? ../Bool/not++let lessThanEqual+    : Integer → Integer → Bool+    = λ(x : Integer) → λ(y : Integer) → Bool/not (lessThan y x)++let example0 = assert : lessThanEqual +5 +6 ≡ True++let example1 = assert : lessThanEqual +5 +5 ≡ True++let example2 = assert : lessThanEqual +5 +4 ≡ False++let example3 = assert : lessThanEqual -5 +8 ≡ True++let example4 = assert : lessThanEqual -5 -3 ≡ True++let example5 = assert : lessThanEqual -3 -5 ≡ False++let example6 = assert : lessThanEqual -3 -3 ≡ True++in  lessThanEqual
+ dhall-lang/Prelude/Integer/multiply view
@@ -0,0 +1,43 @@+{-+`multiply m n` computes `m * n`.+-}++let Integer/abs =+        ./abs sha256:35212fcbe1e60cb95b033a4a9c6e45befca4a298aa9919915999d09e69ddced1+      ? ./abs++let multiply+    : Integer → Integer → Integer+    =   λ(m : Integer)+      → λ(n : Integer)+      → let mAbs = Integer/abs m++        let nAbs = Integer/abs n++        let mNonPos = Natural/isZero (Integer/clamp m)++        let nNonPos = Natural/isZero (Integer/clamp n)++        in        if mNonPos == nNonPos++            then  Natural/toInteger (mAbs * nAbs)++            else  Integer/negate (Natural/toInteger (mAbs * nAbs))++let example0 = assert : multiply +3 +5 ≡ +15++let example1 = assert : multiply -3 +5 ≡ -15++let example2 = assert : multiply -3 -5 ≡ +15++let example3 = assert : multiply +0 +5 ≡ +0++let example4 = assert : multiply +5 +0 ≡ +0++let example5 = assert : multiply +0 +0 ≡ +0++let example6 = assert : multiply +1 +5 ≡ +5++let example7 = assert : multiply +3 -1 ≡ -3++in  multiply
+ dhall-lang/Prelude/Integer/negate view
@@ -0,0 +1,14 @@+{-+Invert the sign of an `Integer`, with zero remaining unchanged.+-}+let negate+    : Integer → Integer+    = Integer/negate++let example0 = assert : negate -3 ≡ +3++let example2 = assert : negate +7 ≡ -7++let example3 = assert : negate +0 ≡ +0++in  negate
dhall-lang/Prelude/Integer/package.dhall view
@@ -1,7 +1,43 @@-{ show =+{ abs =+      ./abs sha256:35212fcbe1e60cb95b033a4a9c6e45befca4a298aa9919915999d09e69ddced1+    ? ./abs+, add =+      ./add sha256:96f1ae60f958febc911935ac4aa2685394642b116b7bddcec7e1ed201a69ed2c+    ? ./add+, clamp =+      ./clamp sha256:ea42096cf3e024fadfaf910e0b839005b0ea7514fff11e5a3950a77694d9c5d2+    ? ./clamp+, equal =+      ./equal sha256:e4414b9eef4142eed6bb0b52eb6fd0074210b68d210e96dd5161697b0f14426a+    ? ./equal+, greaterThan =+      ./greaterThan sha256:accaa6b7cbca7ec2ace4a529e5f3bb57679df2b5ad962bde5b7867d9253d4b8c+    ? ./greaterThan+, greaterThanEqual =+      ./greaterThanEqual sha256:cede1f63b58cb26623148ef741f18e6476ad71d9d541dd54be2b1ec4972a4ad0+    ? ./greaterThanEqual+, lessThan =+      ./lessThan sha256:14cc3bc6ca8757f7c3af338f079fcc18e0c7ee3ed0d20914a9693aec81ae628d+    ? ./lessThan+, lessThanEqual =+      ./lessThanEqual sha256:a849203a9cd270210588f9db23e02b819117a997df1c8131b6f9a634cb2e5c8d+    ? ./lessThanEqual+, multiply =+      ./multiply sha256:71b2a720976c70f0cd06baba9c213867b9744e655927dc3857fa92c864c3cf86+    ? ./multiply+, negate =+      ./negate sha256:2373c992e1de93634bc6a8781eb073b2a92a70170133e49762a785f3a136df5d+    ? ./negate+, show =       ./show sha256:ecf8b0594cd5181bc45d3b7ea0d44d3ba9ad5dac6ec17bb8968beb65f4b1baa9     ? ./show+, subtract =+      ./subtract sha256:8de76d2e235eec1629750ae62e191f13631b36708bfda0425572d87e5a9a37e7+    ? ./subtract , toDouble =       ./toDouble sha256:77bc5d635dc4d952f37cc96f2a681d5ac503b4e8b21fc00055b1946adb5beda7     ? ./toDouble+, toNatural =+      ./toNatural sha256:68dabff205ffdb1ca0df3dabc561ce717b7ae6521c9da9eed893b923ae5a0e1c+    ? ./toNatural }
+ dhall-lang/Prelude/Integer/subtract view
@@ -0,0 +1,56 @@+{-+`subtract m n` computes `n - m`.+-}+let Natural/lessThanEqual =+        ../Natural/lessThanEqual sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99+      ? ../Natural/lessThanEqual++let Integer/abs =+        ./abs sha256:35212fcbe1e60cb95b033a4a9c6e45befca4a298aa9919915999d09e69ddced1+      ? ./abs++let subtract+    : Integer → Integer → Integer+    =   λ(m : Integer)+      → λ(n : Integer)+      → let mAbs = Integer/abs m++        let nAbs = Integer/abs n++        let mNonPos = Natural/isZero (Integer/clamp m)++        let nNonPos = Natural/isZero (Integer/clamp n)++        let diff =+                    if mNonPos == nNonPos++              then        if Natural/lessThanEqual mAbs nAbs++                    then  Integer/negate+                            (Natural/toInteger (Natural/subtract mAbs nAbs))++                    else  Natural/toInteger (Natural/subtract nAbs mAbs)++              else  Natural/toInteger (mAbs + nAbs)++        in  if mNonPos then diff else Integer/negate diff++let example0 = assert : subtract +3 +5 ≡ +2++let example1 = assert : subtract +4 +4 ≡ +0++let example2 = assert : subtract +5 +3 ≡ -2++let example3 = assert : subtract -3 -5 ≡ -2++let example4 = assert : subtract -4 -4 ≡ +0++let example5 = assert : subtract -5 -3 ≡ +2++let example6 = assert : subtract -3 +5 ≡ +8++let example7 = assert : subtract +3 -5 ≡ -8++let example8 = assert : subtract +0 -3 ≡ -3++in  subtract
+ dhall-lang/Prelude/Integer/toNatural view
@@ -0,0 +1,19 @@+{-+Convert an `Integer` to an `Optional Natural`, with negative numbers becoming `None Natural`.+-}+let Integer/lessThan =+        ./lessThan sha256:14cc3bc6ca8757f7c3af338f079fcc18e0c7ee3ed0d20914a9693aec81ae628d+      ? ./lessThan++let toNatural+    : Integer → Optional Natural+    =   λ(n : Integer)+      → if Integer/lessThan n +0 then None Natural else Some (Integer/clamp n)++let example0 = assert : toNatural +7 ≡ Some 7++let example2 = assert : toNatural +0 ≡ Some 0++let example3 = assert : toNatural -3 ≡ None Natural++in  toNatural
dhall-lang/Prelude/JSON/Tagged view
@@ -62,11 +62,8 @@ -} let Tagged     : Type → Type-    =   λ ( a-          : Type-          )-      → { field :-            Text+    =   λ(a : Type)+      → { field : Text         , nesting :               ./Nesting sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335             ? ./Nesting
+ dhall-lang/Prelude/JSON/core.dhall view
@@ -0,0 +1,44 @@+{- A record of functions useful for constructing `JSON` values.++   This is only a subset of what `package.dhall` exports. If you are+   not writing a JSON prelude function, you should use the+   `package.dhall` file instead.++   It is used internally by `render`, `renderYAML` and+   `omitNullFields` instead of `package.dhall` to avoid import+   cycles.+-}+{ Type =+      ./Type sha256:5adb234f5868a5b0eddeb034d690aaba8cb94ea20d0d557003e90334fff6be3e+    ? ./Type+, Tagged =+      ./Tagged sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194+    ? ./Tagged+, Nesting =+      ./Nesting sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335+    ? ./Nesting+, keyText =+      ./keyText sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc+    ? ./keyText+, keyValue =+      ./keyValue sha256:a0a97199d280c4cce72ffcbbf93b7ceda0a569cf4d173ac98e0aaaa78034b98c+    ? ./keyValue+, string =+      ./string sha256:7a8ac435d30a96092d72889f3d48eabf7cba47ecf553fd6bc07a79fdf473e8d2+    ? ./string+, number =+      ./number sha256:534745568065ae19d2b0fe1d09eeb071e9717d0f392187eb0bc95f386b018bec+    ? ./number+, object =+      ./object sha256:a4e047cf157c3971b026b3942a87d474c85950d9b9654f8ebc8631740abf75a9+    ? ./object+, array =+      ./array sha256:3a4c06cf135f4c80619e48c0808f6600d19782705bc59ee7c27cfc2e0f097eb7+    ? ./array+, bool =+      ./bool sha256:018d29f030b45d642aba6bb81bf2c19a7bf183684612ce7a2c8afd2099783c48+    ? ./bool+, null =+      ./null sha256:52c1d45ab2ca54875b444bfb1afdea497c8c9b0652e5044fafd8b16d97f4b78d+    ? ./null+}
+ dhall-lang/Prelude/JSON/omitNullFields view
@@ -0,0 +1,141 @@+{-+This utility omits all `null` record fields, which is often the idiomatic way+for a configuration to encode absent fields+-}+let JSON =+        ./core.dhall sha256:22ba363a8622642e788ffdd8fb98e5a51b1be8ebfcbefe2853e74932078a60af+      ? ./core.dhall++let List/concatMap =+        ../List/concatMap sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64+      ? ../List/concatMap++let List/map =+        ../List/map sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680+      ? ../List/map++let omitNullFields+    : JSON.Type → JSON.Type+    =   λ(old : JSON.Type)+      → λ(JSON : Type)+      → λ ( json+          : { string : Text → JSON+            , number : Double → JSON+            , object : List { mapKey : Text, mapValue : JSON } → JSON+            , array : List JSON → JSON+            , bool : Bool → JSON+            , null : JSON+            }+          )+      → let result =+              old+                { value : JSON, isNull : Bool }+                { string =+                    λ(x : Text) → { value = json.string x, isNull = False }+                , number =+                    λ(x : Double) → { value = json.number x, isNull = False }+                , object =+                      λ ( keyValues+                        : List+                            { mapKey : Text+                            , mapValue : { value : JSON, isNull : Bool }+                            }+                        )+                    → let value =+                            json.object+                              ( List/concatMap+                                  { mapKey : Text+                                  , mapValue : { value : JSON, isNull : Bool }+                                  }+                                  { mapKey : Text, mapValue : JSON }+                                  (   λ ( keyValue+                                        : { mapKey : Text+                                          , mapValue :+                                              { value : JSON, isNull : Bool }+                                          }+                                        )+                                    →       if keyValue.mapValue.isNull++                                      then  [] : List+                                                   { mapKey : Text+                                                   , mapValue : JSON+                                                   }++                                      else  [   keyValue.{ mapKey }+                                              ∧ { mapValue =+                                                    keyValue.mapValue.value+                                                }+                                            ]+                                  )+                                  keyValues+                              )++                      in  { value = value, isNull = False }+                , array =+                      λ(xs : List { value : JSON, isNull : Bool })+                    → let value =+                            json.array+                              ( List/map+                                  { value : JSON, isNull : Bool }+                                  JSON+                                  (   λ(x : { value : JSON, isNull : Bool })+                                    → x.value+                                  )+                                  xs+                              )++                      in  { value = value, isNull = False }+                , bool = λ(x : Bool) → { value = json.bool x, isNull = False }+                , null = { value = json.null, isNull = True }+                }++        in  result.value++let property =+        λ(a : Text)+      → λ(b : Double)+      → λ(c : Bool)+      →   assert+        :   omitNullFields+              ( JSON.object+                  ( toMap+                      { string = JSON.string a+                      , number = JSON.number b+                      , bool = JSON.bool c+                      , null = JSON.null+                      }+                  )+              )+          ≡ JSON.object+              ( toMap+                  { string = JSON.string a+                  , number = JSON.number b+                  , bool = JSON.bool c+                  }+              )++let example =+        assert+      :   omitNullFields+            ( JSON.object+                ( toMap+                    { array =+                        JSON.array [ JSON.object (toMap { null = JSON.null }) ]+                    }+                )+            )+        ≡ JSON.object+            ( toMap+                { array =+                    JSON.array+                      [ JSON.object+                          ([] : List { mapKey : Text, mapValue : JSON.Type })+                      ]+                }+            )++let example =+        assert+      : omitNullFields (JSON.array [ JSON.null ]) ≡ JSON.array [ JSON.null ]++in  omitNullFields
dhall-lang/Prelude/JSON/package.dhall view
@@ -1,37 +1,19 @@-{ Type =-      ./Type sha256:5adb234f5868a5b0eddeb034d690aaba8cb94ea20d0d557003e90334fff6be3e-    ? ./Type-, Tagged =-      ./Tagged sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194-    ? ./Tagged-, Nesting =-      ./Nesting sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335-    ? ./Nesting-, keyText =-      ./keyText sha256:f7b6c802ca5764d03d5e9a6e48d9cb167c01392f775d9c2c87b83cdaa60ea0cc-    ? ./keyText-, keyValue =-      ./keyValue sha256:a0a97199d280c4cce72ffcbbf93b7ceda0a569cf4d173ac98e0aaaa78034b98c-    ? ./keyValue-, string =-      ./string sha256:7a8ac435d30a96092d72889f3d48eabf7cba47ecf553fd6bc07a79fdf473e8d2-    ? ./string-, number =-      ./number sha256:534745568065ae19d2b0fe1d09eeb071e9717d0f392187eb0bc95f386b018bec-    ? ./number-, object =-      ./object sha256:a4e047cf157c3971b026b3942a87d474c85950d9b9654f8ebc8631740abf75a9-    ? ./object-, array =-      ./array sha256:3a4c06cf135f4c80619e48c0808f6600d19782705bc59ee7c27cfc2e0f097eb7-    ? ./array-, bool =-      ./bool sha256:018d29f030b45d642aba6bb81bf2c19a7bf183684612ce7a2c8afd2099783c48-    ? ./bool-, null =-      ./null sha256:52c1d45ab2ca54875b444bfb1afdea497c8c9b0652e5044fafd8b16d97f4b78d-    ? ./null-, render =-      ./render sha256:81f5a84efbb35211b1556838e86d17ed497912cf765bfa4ab76708b21e5371f1-    ? ./render-}+  { render =+        ./render sha256:81f5a84efbb35211b1556838e86d17ed497912cf765bfa4ab76708b21e5371f1+      ? ./render+  , renderYAML =+        ./renderYAML sha256:862b535f6b905f1ce4b83207c58dd53ce5af0026da4c0960a3aec90fdbbb3eb0+      ? ./renderYAML+  , omitNullFields =+        ./omitNullFields sha256:c28270c553f48c406bd161c61776963315e278af5dae9331c4a320c3f4ecb4ec+      ? ./omitNullFields+  , tagInline =+        ./tagInline sha256:49559ac11906ba6cc9eac25753e31e7addb13bc760df108024174c55523984c4+      ? ./tagInline+  , tagNested =+        ./tagNested sha256:93a7415853b7677c832246efadc8e880c1b641a23589286a836a384ca311d26f+      ? ./tagNested+  }+∧ (   ./core.dhall sha256:22ba363a8622642e788ffdd8fb98e5a51b1be8ebfcbefe2853e74932078a60af+    ? ./core.dhall+  )
dhall-lang/Prelude/JSON/render view
@@ -2,34 +2,18 @@     This is useful for debugging `JSON` values or for tests.  For anything    more sophisticated you should use `dhall-to-json` or `dhall-to-yaml`--```-let JSON = ./package.dhall--in  JSON.render-    ( JSON.array-      [ JSON.bool True-      , JSON.string "Hello"-      , JSON.object-        [ { mapKey = "foo", mapValue = JSON.null       }-        , { mapKey = "bar", mapValue = JSON.number 1.0 }-        ]-      ]-    )-= "[ true, \"Hello\", { \"foo\": null, \"bar\": 1.0 } ]"-``` -} let JSON =-        ./Type sha256:5adb234f5868a5b0eddeb034d690aaba8cb94ea20d0d557003e90334fff6be3e-      ? ./Type+        ./core.dhall sha256:22ba363a8622642e788ffdd8fb98e5a51b1be8ebfcbefe2853e74932078a60af+      ? ./core.dhall  let Text/concatMapSep =         ../Text/concatMapSep sha256:c272aca80a607bc5963d1fcb38819e7e0d3e72ac4d02b1183b1afb6a91340840       ? ../Text/concatMapSep  let render-    : JSON → Text-    =   λ(j : JSON)+    : JSON.Type → Text+    =   λ(j : JSON.Type)       → j           Text           { string = λ(x : Text) → Text/show x@@ -44,15 +28,29 @@                           → " ${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 example0 =+        assert+      :   render+            ( JSON.array+                [ JSON.bool True+                , JSON.string "Hello"+                , JSON.object+                    [ { mapKey = "foo", mapValue = JSON.null }+                    , { mapKey = "bar", mapValue = JSON.number 1.0 }+                    ]+                ]+            )+        ≡ "[ true, \"Hello\", { \"foo\": null, \"bar\": 1.0 } ]"  in  render
+ dhall-lang/Prelude/JSON/renderYAML view
@@ -0,0 +1,175 @@+{- Render a `JSON` value as `Text` in YAML format.++   The generated YAML text will only contain escaped object keys and+   string values and might therefore not be very human readable.++   However, it is useful for debugging `JSON` values or for tests.+   For anything more sophisticated you should use `dhall-to-json` or+   `dhall-to-yaml`.+-}++let JSON =+        ./core.dhall sha256:22ba363a8622642e788ffdd8fb98e5a51b1be8ebfcbefe2853e74932078a60af+      ? ./core.dhall++let Text/concatSep =+        ../Text/concatSep sha256:e4401d69918c61b92a4c0288f7d60a6560ca99726138ed8ebc58dca2cd205e58+      ? ../Text/concatSep++let List/drop =+        ../List/drop sha256:af983ba3ead494dd72beed05c0f3a17c36a4244adedf7ced502c6512196ed0cf+      ? ../List/drop++let List/null =+        ../List/null sha256:2338e39637e9a50d66ae1482c0ed559bbcc11e9442bfca8f8c176bbcd9c4fc80+      ? ../List/null++let List/map =+        ../List/map sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680+      ? ../List/map++let List/concatMap =+        ../List/concatMap sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64+      ? ../List/concatMap++let Optional/map =+        ../Optional/map sha256:e7f44219250b89b094fbf9996e04b5daafc0902d864113420072ae60706ac73d+      ? ../Optional/map++let NonEmpty+    : Type → Type+    = λ(a : Type) → { head : a, tail : List a }++let uncons+    : ∀(a : Type) → List a → Optional (NonEmpty a)+    =   λ(a : Type)+      → λ(ls : List a)+      → Optional/map+          a+          (NonEmpty a)+          (λ(head : a) → { head = head, tail = List/drop 1 a ls })+          (List/head a ls)++let nonEmptyToList+    : ∀(a : Type) → NonEmpty a → List a+    = λ(a : Type) → λ(nonEmpty : NonEmpty a) → [ nonEmpty.head ] # nonEmpty.tail++let concatNonEmpty+    : ∀(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 (nonEmptyToList a) lss.tail+        }++let Block+    : Type+    = NonEmpty Text++let indentBlockWith+    : Text → Text → Block → Block+    =   λ(headIndent : Text)+      → λ(tailIndent : Text)+      → λ(block : Block)+      → { head = headIndent ++ block.head+        , tail = List/map Text Text (λ(t : Text) → tailIndent ++ t) block.tail+        }++let manyBlocks+    : Block → List Block → Block+    =   λ(ifEmpty : Block)+      → λ(blocks : List Block)+      → Optional/fold+          (NonEmpty Block)+          (uncons Block blocks)+          Block+          (concatNonEmpty Text)+          ifEmpty++let singleLine+    : Text → Block+    = λ(text : Text) → { head = text, tail = [] : List Text }++let indentKeyedBlock+    : Text → Text → Text → Block → Block+    =   λ(key : Text)+      → λ(spacer : Text)+      → λ(indentation : Text)+      → λ(block : Block)+      →       if List/null Text block.tail++        then  singleLine (key ++ spacer ++ block.head)++        else  indentBlockWith+                key+                indentation+                { head = "", tail = nonEmptyToList Text block }++let blockToText+    : Block → Text+    = λ(block : Block) → Text/concatSep "\n" (nonEmptyToList Text block) ++ "\n"++let renderYAML+    : JSON.Type → Text+    =   λ(json : JSON.Type)+      → let ObjectField = { mapKey : Text, mapValue : Block }++        in  blockToText+              ( json+                  Block+                  { string = λ(x : Text) → singleLine (Text/show x)+                  , number = λ(x : Double) → singleLine (Double/show x)+                  , object =+                        λ(fields : List ObjectField)+                      → manyBlocks+                          (singleLine "{}")+                          ( List/map+                              ObjectField+                              Block+                              (   λ(e : ObjectField)+                                → indentKeyedBlock+                                    "! ${Text/show e.mapKey}:"+                                    " "+                                    "  "+                                    e.mapValue+                              )+                              fields+                          )+                  , array =+                        λ(elements : List Block)+                      → manyBlocks+                          (singleLine "[]")+                          ( List/map+                              Block+                              Block+                              (indentBlockWith "- " "  ")+                              elements+                          )+                  , bool =+                      λ(x : Bool) → singleLine (if x then "true" else "false")+                  , null = singleLine "null"+                  }+              )++let example0 =+        assert+      :   renderYAML+            ( JSON.array+                [ JSON.bool True+                , JSON.string "Hello"+                , JSON.object+                    [ { mapKey = "foo", mapValue = JSON.null }+                    , { mapKey = "bar", mapValue = JSON.number 1.0 }+                    ]+                ]+            )+        ≡ ''+          - true+          - "Hello"+          - ! "foo": null+            ! "bar": 1.0+          ''++in  renderYAML
+ dhall-lang/Prelude/JSON/tagInline view
@@ -0,0 +1,28 @@+{- Prepare a union value for JSON- or YAML-encoding with the inline layout+-}+let Nesting =+        ./Nesting sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335+      ? ./Nesting++let Tagged =+        ./Tagged sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194+      ? ./Tagged++let tagInline+    : Text → ∀(a : Type) → a → Tagged a+    =   λ(tagFieldName : Text)+      → λ(a : Type)+      → λ(contents : a)+      → { nesting = Nesting.Inline, field = tagFieldName, contents = contents }++let example0 =+      let Example = < Left : { foo : Natural } | Right : { bar : Bool } >++      in    assert+          :   tagInline "name" Example (Example.Left { foo = 2 })+            ≡ { field = "name"+              , nesting = Nesting.Inline+              , contents = Example.Left { foo = 2 }+              }++in  tagInline
+ dhall-lang/Prelude/JSON/tagNested view
@@ -0,0 +1,32 @@+{- Prepare a union value for JSON- or YAML-encoding with the nested layout+-}+let Nesting =+        ./Nesting sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335+      ? ./Nesting++let Tagged =+        ./Tagged sha256:21feca7d2b23f210d0696131d792e18a7d24fdcc85d41a49ba85b98670eba194+      ? ./Tagged++let tagNested+    : Text → Text → ∀(a : Type) → a → Tagged a+    =   λ(contentsFieldName : Text)+      → λ(tagFieldName : Text)+      → λ(a : Type)+      → λ(contents : a)+      → { nesting = Nesting.Nested contentsFieldName+        , field = tagFieldName+        , contents = contents+        }++let example0 =+      let Example = < Left : { foo : Natural } | Right : { bar : Bool } >++      in    assert+          :   tagNested "value" "name" Example (Example.Left { foo = 2 })+            ≡ { field = "name"+              , nesting = Nesting.Nested "value"+              , contents = Example.Left { foo = 2 }+              }++in  tagNested
+ dhall-lang/Prelude/List/drop view
@@ -0,0 +1,29 @@+-- Remove first `n` elements of a list+let Natural/greaterThanEqual =+        ../Natural/greaterThanEqual sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4+      ? ../Natural/greaterThanEqual++let drop+    : ∀(n : Natural) → ∀(a : Type) → List a → List a+    =   λ(n : Natural)+      → λ(a : Type)+      → λ(xs : List a)+      → List/fold+          { index : Natural, value : a }+          (List/indexed a xs)+          (List a)+          (   λ(x : { index : Natural, value : a })+            → λ(xs : List a)+            →       if Natural/greaterThanEqual x.index n++              then  [ x.value ] # xs++              else  xs+          )+          ([] : List a)++let example = assert : drop 2 Natural [ 2, 3, 5 ] ≡ [ 5 ]++let example = assert : drop 5 Natural [ 2, 3, 5 ] ≡ ([] : List Natural)++in  drop
dhall-lang/Prelude/List/package.dhall view
@@ -16,6 +16,9 @@ , default =       ./default sha256:0ed2a04df6c1d55c08bcdbad82b30980af9ac40d2df7a1628f3663e3e8b4fe01     ? ./default+, drop =+      ./drop sha256:af983ba3ead494dd72beed05c0f3a17c36a4244adedf7ced502c6512196ed0cf+    ? ./drop , empty =       ./empty sha256:b2f561f35098c457353723c93a22bd5de28d26ecc5370814bef9dfda421e0147     ? ./empty@@ -49,6 +52,9 @@ , null =       ./null sha256:2338e39637e9a50d66ae1482c0ed559bbcc11e9442bfca8f8c176bbcd9c4fc80     ? ./null+, partition =+      ./partition sha256:38147ac6d750a6492736dd90cc967bf09aa405c499de943c64fab7b86ae02f03+    ? ./partition , replicate =       ./replicate sha256:d4250b45278f2d692302489ac3e78280acb238d27541c837ce46911ff3baa347     ? ./replicate@@ -58,6 +64,9 @@ , shifted =       ./shifted sha256:54fb22c7e952ebce1cfc0fcdd33ce4cfa817bff9d6564af268dea6685f8b5dfe     ? ./shifted+, take =+      ./take sha256:b3e08ee8c3a5bf3d8ccee6b2b2008fbb8e51e7373aef6f1af67ad10078c9fbfa+    ? ./take , unzip =       ./unzip sha256:4d6003e9e683a289fe33f4c90f958eb1e08ea0bbb474210fcd90d1885c9660e9     ? ./unzip
+ dhall-lang/Prelude/List/partition view
@@ -0,0 +1,33 @@+{-+`partition` divides a `List` of elements into those that satisfy a predicate+and those that do not+-}+let Partition+    : Type → Type+    = λ(a : Type) → { true : List a, false : List a }++let partition+    : ∀(a : Type) → (a → Bool) → List a → Partition a+    =   λ(a : Type)+      → λ(f : a → Bool)+      → λ(xs : List a)+      → List/fold+          a+          xs+          (Partition a)+          (   λ(x : a)+            → λ(p : Partition a)+            →       if f x++              then  { true = [ x ] # p.true, false = p.false }++              else  { true = p.true, false = [ x ] # p.false }+          )+          { true = [] : List a, false = [] : List a }++let example0 =+        assert+      :   partition Natural Natural/even [ 0, 1, 2, 3 ]+        ≡ { true = [ 0, 2 ], false = [ 1, 3 ] }++in  partition
dhall-lang/Prelude/List/shifted view
@@ -22,7 +22,7 @@                         → λ(y : { count : Natural, diff : Natural → list })                         → let length =                                 List/length { index : Natural, value : a } kvs-                          +                           in  { count = y.count + length                               , diff =                                     λ(n : Natural)@@ -38,14 +38,14 @@                                                 { index = kvOld.index + n                                                 , value = kvOld.value                                                 }-                                          +                                           in  cons kvNew z                                       )                                       (y.diff (n + length))                               }                       )                       { count = 0, diff = λ(_ : Natural) → nil }-              +               in  result.diff 0           ) 
+ dhall-lang/Prelude/List/take view
@@ -0,0 +1,25 @@+-- Truncate a list to the first `n` elements+let Natural/lessThan =+        ../Natural/lessThan sha256:3381b66749290769badf8855d8a3f4af62e8de52d1364d838a9d1e20c94fa70c+      ? ../Natural/lessThan++let take+    : ∀(n : Natural) → ∀(a : Type) → List a → List a+    =   λ(n : Natural)+      → λ(a : Type)+      → λ(xs : List a)+      → List/fold+          { index : Natural, value : a }+          (List/indexed a xs)+          (List a)+          (   λ(x : { index : Natural, value : a })+            → λ(xs : List a)+            → if Natural/lessThan x.index n then [ x.value ] # xs else xs+          )+          ([] : List a)++let example = assert : take 2 Natural [ 2, 3, 5 ] ≡ [ 2, 3 ]++let example = assert : take 5 Natural [ 2, 3, 5 ] ≡ [ 2, 3, 5 ]++in  take
+ dhall-lang/Prelude/Natural/listMax view
@@ -0,0 +1,28 @@+{-+`listMax` returns the largest element of a `List` or `None Natural` if the+`List` is empty+-}+let max =+        ./max sha256:1f3b18da330223ab039fad11693da72c7e68d516f50502c73f41a89a097b62f7+      ? ./max++let Optional/map =+        ../Optional/map sha256:e7f44219250b89b094fbf9996e04b5daafc0902d864113420072ae60706ac73d+      ? ../Optional/map++let listMax+    : List Natural → Optional Natural+    =   λ(xs : List Natural)+      → Optional/map+          Natural+          Natural+          (λ(n : Natural) → List/fold Natural xs Natural max n)+          (List/head Natural xs)++let example0 = assert : listMax [ 1, 2 ] ≡ Some 2++let example1 = assert : listMax ([] : List Natural) ≡ None Natural++let property0 = λ(n : Natural) → assert : listMax [ n ] ≡ Some n++in  listMax
+ dhall-lang/Prelude/Natural/listMin view
@@ -0,0 +1,32 @@+{-+`listMin` returns the smallest element of a `List` or `None Natural` if the+`List` is empty+-}+let min =+        ./min sha256:f25f9c462e4dbf0eb15f9ff6ac840c6e9c82255a7f4f2ab408bdab338e028710+      ? ./min++let Optional/map =+        ../Optional/map sha256:e7f44219250b89b094fbf9996e04b5daafc0902d864113420072ae60706ac73d+      ? ../Optional/map++let listMin+    : List Natural → Optional Natural+    =   λ(xs : List Natural)+      → Optional/map+          Natural+          Natural+          (   λ(n : Natural)+            → if Natural/isZero n then n else List/fold Natural xs Natural min n+          )+          (List/head Natural xs)++let example0 = assert : listMin [ 0, 1 ] ≡ Some 0++let example1 = assert : listMin ([] : List Natural) ≡ None Natural++let example2 = assert : listMin [ 3, 2, 1 ] ≡ Some 1++let property0 = λ(n : Natural) → assert : listMin [ n ] ≡ Some n++in  listMin
+ dhall-lang/Prelude/Natural/max view
@@ -0,0 +1,20 @@+{-+`max a b` returns the larger of `a` or `b`+-}+let lessThanEqual =+        ./lessThanEqual sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99+      ? ./lessThanEqual++let max+    : Natural → Natural → Natural+    = λ(a : Natural) → λ(b : Natural) → if lessThanEqual a b then b else a++let example0 = assert : max 1 2 ≡ 2++let example1 = assert : max 2 1 ≡ 2++let property0 = λ(n : Natural) → assert : max n n ≡ n++let property1 = λ(n : Natural) → assert : max 0 n ≡ n++in  max
+ dhall-lang/Prelude/Natural/min view
@@ -0,0 +1,18 @@+{-+`min a b` returns the smaller of `a` or `b`+-}+let lessThanEqual =+        ./lessThanEqual sha256:1a5caa2b80a42b9f58fff58e47ac0d9a9946d0b2d36c54034b8ddfe3cb0f3c99+      ? ./lessThanEqual++let min+    : Natural → Natural → Natural+    = λ(a : Natural) → λ(b : Natural) → if lessThanEqual a b then a else b++let example0 = assert : min 1 2 ≡ 1++let example1 = assert : min 2 1 ≡ 1++let property0 = λ(n : Natural) → assert : min n n ≡ n++in  min
dhall-lang/Prelude/Natural/package.dhall view
@@ -46,6 +46,21 @@ , greaterThan =       ./greaterThan sha256:f702abcdfcd7ad73619b9285d7e41c3a1d017fb6b8d037cf40bd93bf30c09b2c     ? ./greaterThan+, min =+      ./min sha256:f25f9c462e4dbf0eb15f9ff6ac840c6e9c82255a7f4f2ab408bdab338e028710+    ? ./min+, max =+      ./max sha256:1f3b18da330223ab039fad11693da72c7e68d516f50502c73f41a89a097b62f7+    ? ./max+, listMin =+      ./listMin sha256:89e0d9c23750efd8a8a2a6945579f21e46bd503b0655d4bfdd0e0e51e39c37cc+    ? ./listMin+, listMax =+      ./listMax sha256:30917e8ca230ea6044c6d8ea6e72bcf6f76437aaecc347f790e8a5946c6aa0e5+    ? ./listMax+, sort =+      ./sort sha256:ed2eb5a33c5c96ac9227b0b4c77bdbf8911026d721c603ac897ae84b2bfb5dcd+    ? ./sort , subtract =       ./subtract sha256:b9277ac637d09142a3a3ac79137ef5955c42f8b33b6746d59db2c9d75ccdd745     ? ./subtract
+ dhall-lang/Prelude/Natural/sort view
@@ -0,0 +1,60 @@+{-+`sort` sorts a `List` of `Natural`s in ascending order+-}+let greaterThanEqual =+        ./greaterThanEqual sha256:30ebfab0febd7aa0ccccfdf3dc36ee6d50f0117f35dd4a9b034750b7e885a1a4+      ? ./greaterThanEqual++let listMin =+        ./listMin sha256:89e0d9c23750efd8a8a2a6945579f21e46bd503b0655d4bfdd0e0e51e39c37cc+      ? ./listMin++let List/partition =+        ../List/partition sha256:38147ac6d750a6492736dd90cc967bf09aa405c499de943c64fab7b86ae02f03+      ? ../List/partition++let Accumulator = { sorted : List Natural, rest : List Natural }++let partitionMinima =+        λ(xs : List Natural)+      → Optional/fold+          Natural+          (listMin xs)+          { true : List Natural, false : List Natural }+          (λ(m : Natural) → List/partition Natural (greaterThanEqual m) xs)+          { true = [] : List Natural, false = [] : List Natural }++let test0 =+        assert+      : partitionMinima [ 2, 1, 1, 3 ] ≡ { true = [ 1, 1 ], false = [ 2, 3 ] }++let step =+        λ(x : Accumulator)+      → let p = partitionMinima x.rest++        in  { sorted = x.sorted # p.true, rest = p.false }++let test1 =+        assert+      :   step { sorted = [ 1, 1 ], rest = [ 2, 3 ] }+        ≡ { sorted = [ 1, 1, 2 ], rest = [ 3 ] }++let sort+    : List Natural → List Natural+    =   λ(xs : List Natural)+      → let x =+              Natural/fold+                (List/length Natural xs)+                Accumulator+                step+                { sorted = [] : List Natural, rest = xs }++        in  x.sorted++let example0 = assert : sort ([] : List Natural) ≡ ([] : List Natural)++let example1 = assert : sort [ 1 ] ≡ [ 1 ]++let example2 = assert : sort [ 3, 2, 1, 3, 2, 1 ] ≡ [ 1, 1, 2, 2, 3, 3 ]++in  sort
dhall-lang/Prelude/Text/concatMapSep view
@@ -26,7 +26,7 @@                       status                 )                 Status.Empty-        +         in  merge { Empty = "", NonEmpty = λ(result : Text) → result } status  let example0 =
dhall-lang/Prelude/Text/concatSep view
@@ -23,7 +23,7 @@                       status                 )                 Status.Empty-        +         in  merge { Empty = "", NonEmpty = λ(result : Text) → result } status  let example0 = assert : concatSep ", " [ "ABC", "DEF", "GHI" ] ≡ "ABC, DEF, GHI"
dhall-lang/Prelude/Text/show view
@@ -9,6 +9,11 @@ let example0 = assert : show "ABC" ≡ "\"ABC\""  let example1 =-      assert : show "\u0000 \$ \\ \n ☺" ≡ "\"\\u0000 \\u0024 \\\\ \\n ☺\""+        assert+      :   show+            ''+            ${"\u0000"} $ \ +            ${" "}☺''+        ≡ "\"\\u0000 \\u0024 \\\\ \\n ☺\""  in  show
dhall-lang/Prelude/XML/render view
@@ -52,13 +52,13 @@                     }                   )               → let attribs = Text/concatMap Attr renderAttr elem.attributes-                +                 in      "<${elem.name}${attribs}"                     ++  (       if Natural/isZero                                      (List/length Text elem.content)-                          +                           then  "/>"-                          +                           else  ">${Text/concat elem.content}</${elem.name}>"                         )           }
dhall-lang/Prelude/package.dhall view
@@ -8,10 +8,10 @@       ./Function/package.dhall sha256:74c3822b98b9d37f9f820af8e1a7ee790bcfac03050eabd45af4a255fb93e026     ? ./Function/package.dhall , Integer =-      ./Integer/package.dhall sha256:eb464566d3192dd16ce915a9bd874aaaad612d5c69beb356e5b7d2e0c4949dcf+      ./Integer/package.dhall sha256:dbc82e5542a642b9372ce6126967028c0cade2b8ad6923312b086b686ad67e06     ? ./Integer/package.dhall , List =-      ./List/package.dhall sha256:88ae09f29981480e62a39c925011b3246d716a80871440f071cf981efea1ad5e+      ./List/package.dhall sha256:f0fdab7ab30415c128d89424589c42a15c835338be116fa14484086e4ba118d7     ? ./List/package.dhall , Location =       ./Location/package.dhall sha256:0eb4e4a60814018009c720f6820aaa13cf9491eb1b09afb7b832039c6ee4d470@@ -23,13 +23,13 @@       ./Monoid sha256:26fafa098600ef7a54ef9dba5ada416bbbdd21df1af306c052420c61553ad4af     ? ./Monoid , Natural =-      ./Natural/package.dhall sha256:4574df29e6bb82fd894c311f6c2ad9a22574756eb62f06d475aa8306d25006fc+      ./Natural/package.dhall sha256:e230d4ee318826ab9517ae5d6f38d1a9359d7cff815cc32912cc6b991656bb1a     ? ./Natural/package.dhall , Optional =       ./Optional/package.dhall sha256:7608f2d38dabee8bfe6865b4adc11289059984220f422d2b023b15b3908f7a4c     ? ./Optional/package.dhall , JSON =-      ./JSON/package.dhall sha256:0c3c40a63108f2e6ad59f23b789c18eb484d0e9aebc9416c5a4f338c6753084b+      ./JSON/package.dhall sha256:843783d29e60b558c2de431ce1206ce34bdfde375fcf06de8ec5bf77092fdef7     ? ./JSON/package.dhall , Text =       ./Text/package.dhall sha256:0a0ad9f649aed94c2680491efb384925b5b2bb5b353f1b8a7eb134955c1ffe45
+ dhall-lang/tests/binary-decode/success/unit/IntegerBigNegativeA.dhallb view
@@ -0,0 +1,1 @@+‚ÃIÿÿÿÿÿÿÿÿ
+ dhall-lang/tests/binary-decode/success/unit/IntegerBigNegativeB.dhall view
@@ -0,0 +1,2 @@+{- -2^65 -}+-36893488147419103232
+ dhall-lang/tests/binary-decode/success/unit/IntegerBigPositiveA.dhallb view

binary file changed (absent → 13 bytes)

+ dhall-lang/tests/binary-decode/success/unit/IntegerBigPositiveB.dhall view
@@ -0,0 +1,2 @@+{- 2^65 -}++36893488147419103232
+ dhall-lang/tests/binary-decode/success/unit/NaturalBigA.dhallb view

binary file changed (absent → 13 bytes)

+ dhall-lang/tests/binary-decode/success/unit/NaturalBigB.dhall view
@@ -0,0 +1,2 @@+{- 2^65 -}+36893488147419103232
+ dhall-lang/tests/import/success/referentiallyTransparentMissing.dhall view
@@ -0,0 +1,9 @@+{- This test verifies that `missing` is treated as a referentially transparent+   import.  The following import contains a `missing as Location` in its+   test assertion that should succeed since:++   * The `missing` is never actually resolved (due to the `as Location`)+   * The `missing` should be treated as referentially transparent (and therefore+     be a valid transitive dependency of a remote import)+-}+https://prelude.dhall-lang.org/v11.0.0/Location/Type
+ dhall-lang/tests/normalization/success/unit/IntegerClampA.dhall view
@@ -0,0 +1,1 @@+Integer/clamp
+ dhall-lang/tests/normalization/success/unit/IntegerClampB.dhall view
@@ -0,0 +1,1 @@+Integer/clamp
+ dhall-lang/tests/normalization/success/unit/IntegerClampNegativeA.dhall view
@@ -0,0 +1,1 @@+Integer/clamp -6
+ dhall-lang/tests/normalization/success/unit/IntegerClampNegativeB.dhall view
@@ -0,0 +1,1 @@+0
+ dhall-lang/tests/normalization/success/unit/IntegerClampPositiveA.dhall view
@@ -0,0 +1,1 @@+Integer/clamp +5
+ dhall-lang/tests/normalization/success/unit/IntegerClampPositiveB.dhall view
@@ -0,0 +1,1 @@+5
+ dhall-lang/tests/normalization/success/unit/IntegerClampZeroA.dhall view
@@ -0,0 +1,1 @@+Integer/clamp +0
+ dhall-lang/tests/normalization/success/unit/IntegerClampZeroB.dhall view
@@ -0,0 +1,1 @@+0
+ dhall-lang/tests/normalization/success/unit/IntegerNegateA.dhall view
@@ -0,0 +1,1 @@+Integer/negate
+ dhall-lang/tests/normalization/success/unit/IntegerNegateB.dhall view
@@ -0,0 +1,1 @@+Integer/negate
+ dhall-lang/tests/normalization/success/unit/IntegerNegateNegativeA.dhall view
@@ -0,0 +1,1 @@+Integer/negate -7
+ dhall-lang/tests/normalization/success/unit/IntegerNegateNegativeB.dhall view
@@ -0,0 +1,1 @@++7
+ dhall-lang/tests/normalization/success/unit/IntegerNegatePositiveA.dhall view
@@ -0,0 +1,1 @@+Integer/negate +3
+ dhall-lang/tests/normalization/success/unit/IntegerNegatePositiveB.dhall view
@@ -0,0 +1,1 @@+-3
+ dhall-lang/tests/normalization/success/unit/IntegerNegateZeroA.dhall view
@@ -0,0 +1,1 @@+Integer/negate +0
+ dhall-lang/tests/normalization/success/unit/IntegerNegateZeroB.dhall view
@@ -0,0 +1,1 @@++0
dhall-lang/tests/normalization/success/unit/ListBuildFoldFusionB.dhall view
@@ -1,1 +1,8 @@-λ(T : Type) → λ(x : List T) → x+  λ(T : Type)+→ λ(x : List T)+→ List/fold+    T+    x+    (List T)+    (λ(a : T) → λ(`as` : List T) → [ a ] # `as`)+    ([] : List T)
dhall-lang/tests/normalization/success/unit/NaturalBuildFoldFusionB.dhall view
@@ -1,1 +1,1 @@-λ(x : Natural) → x+λ(x : Natural) → Natural/fold x Natural (λ(n : Natural) → n + 1) 0
dhall-lang/tests/normalization/success/unit/OptionalBuildFoldFusionB.dhall view
@@ -1,1 +1,3 @@-λ(T : Type) → λ(x : Optional T) → x+  λ(T : Type)+→ λ(x : Optional T)+→ Optional/fold T x (Optional T) (λ(a : T) → Some a) (None T)
+ dhall-lang/tests/parser/failure/nonCharacterUnbraced.dhall view
@@ -0,0 +1,6 @@+{-+The parser should reject unicode escape sequences for non-characters+(0xNFFFE-0xNFFFF for each `N` in `{ 0 .. F }), regardless of whether they are+braced or not.+-}+"\uFFFE"
+ dhall-lang/tests/parser/failure/surrogatePairUnbraced.dhall view
@@ -0,0 +1,5 @@+{-+The parser should reject unicode escape sequences for surrogate pairs+(0xD800-DFFF), regardless of whether they are braced or not.+-}+"\uD800"
+ dhall-lang/tests/parser/success/missingFooA.dhall view
@@ -0,0 +1,1 @@+missingFoo
+ dhall-lang/tests/parser/success/missingFooB.dhallb view

binary file changed (absent → 13 bytes)

+ dhall-lang/tests/parser/success/missingInParenthesesA.dhall view
@@ -0,0 +1,1 @@+(missing)
+ dhall-lang/tests/parser/success/missingInParenthesesB.dhallb view

binary file changed (absent → 6 bytes)

+ dhall-lang/tests/parser/success/missingSlashA.dhall view
@@ -0,0 +1,1 @@+missing/
+ dhall-lang/tests/parser/success/missingSlashB.dhallb view

binary file changed (absent → 11 bytes)

+ dhall-lang/tests/parser/success/preferMissingNoSpacesA.dhall view
@@ -0,0 +1,1 @@+missing//foo
+ dhall-lang/tests/parser/success/preferMissingNoSpacesB.dhallb view

binary file changed (absent → 15 bytes)

+ dhall-lang/tests/parser/success/text/nonAssignedUnicodeA.dhall view
@@ -0,0 +1,1 @@+"\u{1FFF0}"
+ dhall-lang/tests/parser/success/text/nonAssignedUnicodeB.dhallb view
@@ -0,0 +1,1 @@+‚d🿰
dhall-lang/tests/parser/success/unit/CompletionA.dhall view
@@ -1,1 +1,1 @@-T::r+T :: r
dhall-lang/tests/type-inference/success/preludeB.dhall view
@@ -21,7 +21,22 @@         → ∀(x : A)         → C     }-, Integer : { show : Integer → Text, toDouble : Integer → Double }+, Integer :+    { abs : ∀(n : Integer) → Natural+    , add : ∀(m : Integer) → ∀(n : Integer) → Integer+    , clamp : Integer → Natural+    , equal : ∀(a : Integer) → ∀(b : Integer) → Bool+    , greaterThan : ∀(x : Integer) → ∀(y : Integer) → Bool+    , greaterThanEqual : ∀(x : Integer) → ∀(y : Integer) → Bool+    , lessThan : ∀(x : Integer) → ∀(y : Integer) → Bool+    , lessThanEqual : ∀(x : Integer) → ∀(y : Integer) → Bool+    , multiply : ∀(m : Integer) → ∀(n : Integer) → Integer+    , negate : Integer → Integer+    , show : Integer → Text+    , subtract : ∀(m : Integer) → ∀(n : Integer) → Integer+    , toDouble : Integer → Double+    , toNatural : ∀(n : Integer) → Optional Natural+    } , JSON :     { Nesting : Type     , Tagged : ∀(a : Type) → Type@@ -129,6 +144,31 @@               }             )         → JSON+    , omitNullFields :+          ∀ ( old+            :   ∀(JSON : Type)+              → ∀ ( json+                  : { array : List JSON → JSON+                    , bool : Bool → JSON+                    , null : JSON+                    , number : Double → JSON+                    , object : List { mapKey : Text, mapValue : JSON } → JSON+                    , string : Text → JSON+                    }+                  )+              → JSON+            )+        → ∀(JSON : Type)+        → ∀ ( json+            : { array : List JSON → JSON+              , bool : Bool → JSON+              , null : JSON+              , number : Double → JSON+              , object : List { mapKey : Text, mapValue : JSON } → JSON+              , string : Text → JSON+              }+            )+        → JSON     , render :           ∀ ( j             :   ∀(JSON : Type)@@ -144,6 +184,21 @@               → JSON             )         → Text+    , renderYAML :+          ∀ ( json+            :   ∀(JSON : Type)+              → ∀ ( json+                  : { array : List JSON → JSON+                    , bool : Bool → JSON+                    , null : JSON+                    , number : Double → JSON+                    , object : List { mapKey : Text, mapValue : JSON } → JSON+                    , string : Text → JSON+                    }+                  )+              → JSON+            )+        → Text     , string :           ∀(x : Text)         → ∀(JSON : Type)@@ -157,6 +212,17 @@               }             )         → JSON+    , tagInline :+          ∀(tagFieldName : Text)+        → ∀(a : Type)+        → ∀(contents : a)+        → { contents : a, field : Text, nesting : < Inline | Nested : Text > }+    , tagNested :+          ∀(contentsFieldName : Text)+        → ∀(tagFieldName : Text)+        → ∀(a : Type)+        → ∀(contents : a)+        → { contents : a, field : Text, nesting : < Inline | Nested : Text > }     } , List :     { all : ∀(a : Type) → ∀(f : a → Bool) → ∀(xs : List a) → Bool@@ -169,6 +235,7 @@     , concatMap :         ∀(a : Type) → ∀(b : Type) → ∀(f : a → List b) → ∀(xs : List a) → List b     , default : ∀(a : Type) → ∀(o : Optional (List a)) → List a+    , 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     , fold :@@ -186,12 +253,18 @@     , length : ∀(a : Type) → List a → Natural     , map : ∀(a : Type) → ∀(b : Type) → ∀(f : a → b) → ∀(xs : List a) → List b     , null : ∀(a : Type) → ∀(xs : List a) → Bool+    , partition :+          ∀(a : Type)+        → ∀(f : a → Bool)+        → ∀(xs : List a)+        → { false : List a, true : List a }     , replicate : ∀(n : Natural) → ∀(a : Type) → ∀(x : a) → List a     , reverse : ∀(a : Type) → List a → List a     , shifted :           ∀(a : Type)         → ∀(kvss : List (List { index : Natural, value : a }))         → List { index : Natural, value : a }+    , take : ∀(n : Natural) → ∀(a : Type) → ∀(xs : List a) → List a     , unzip :           ∀(a : Type)         → ∀(b : Type)@@ -251,9 +324,14 @@     , isZero : Natural → Bool     , lessThan : ∀(x : Natural) → ∀(y : Natural) → Bool     , lessThanEqual : ∀(x : Natural) → ∀(y : Natural) → Bool+    , listMax : ∀(xs : List Natural) → Optional Natural+    , listMin : ∀(xs : List Natural) → Optional Natural+    , max : ∀(a : Natural) → ∀(b : Natural) → Natural+    , min : ∀(a : Natural) → ∀(b : Natural) → Natural     , odd : Natural → Bool     , product : ∀(xs : List Natural) → Natural     , show : Natural → Text+    , sort : ∀(xs : List Natural) → List Natural     , subtract : Natural → Natural → Natural     , sum : ∀(xs : List Natural) → Natural     , toDouble : ∀(n : Natural) → Double
+ dhall-lang/tests/type-inference/success/unit/IntegerClampA.dhall view
@@ -0,0 +1,1 @@+Integer/clamp
+ dhall-lang/tests/type-inference/success/unit/IntegerClampB.dhall view
@@ -0,0 +1,1 @@+Integer → Natural
+ dhall-lang/tests/type-inference/success/unit/IntegerNegateA.dhall view
@@ -0,0 +1,1 @@+Integer/negate
+ dhall-lang/tests/type-inference/success/unit/IntegerNegateB.dhall view
@@ -0,0 +1,1 @@+Integer → Integer
dhall.cabal view
@@ -1,5 +1,5 @@ Name: dhall-Version: 1.27.0+Version: 1.28.0 Cabal-Version: >=1.10 Build-Type: Simple Tested-With: GHC == 7.10.3, GHC == 8.4.3, GHC == 8.6.1@@ -40,28 +40,46 @@     dhall-lang/Prelude/Double/show     dhall-lang/Prelude/Function/compose     dhall-lang/Prelude/Function/package.dhall+    dhall-lang/Prelude/Integer/abs+    dhall-lang/Prelude/Integer/add+    dhall-lang/Prelude/Integer/clamp+    dhall-lang/Prelude/Integer/equal+    dhall-lang/Prelude/Integer/greaterThan+    dhall-lang/Prelude/Integer/greaterThanEqual+    dhall-lang/Prelude/Integer/lessThan+    dhall-lang/Prelude/Integer/lessThanEqual+    dhall-lang/Prelude/Integer/multiply+    dhall-lang/Prelude/Integer/negate     dhall-lang/Prelude/Integer/package.dhall     dhall-lang/Prelude/Integer/show+    dhall-lang/Prelude/Integer/subtract     dhall-lang/Prelude/Integer/toDouble+    dhall-lang/Prelude/Integer/toNatural+    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/keyText     dhall-lang/Prelude/JSON/keyValue-    dhall-lang/Prelude/JSON/Nesting     dhall-lang/Prelude/JSON/null     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/renderYAML     dhall-lang/Prelude/JSON/string-    dhall-lang/Prelude/JSON/Tagged-    dhall-lang/Prelude/JSON/Type+    dhall-lang/Prelude/JSON/tagInline+    dhall-lang/Prelude/JSON/tagNested     dhall-lang/Prelude/List/all     dhall-lang/Prelude/List/any     dhall-lang/Prelude/List/build     dhall-lang/Prelude/List/concat     dhall-lang/Prelude/List/concatMap     dhall-lang/Prelude/List/default+    dhall-lang/Prelude/List/drop     dhall-lang/Prelude/List/empty     dhall-lang/Prelude/List/filter     dhall-lang/Prelude/List/fold@@ -74,20 +92,22 @@     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     dhall-lang/Prelude/List/shifted+    dhall-lang/Prelude/List/take     dhall-lang/Prelude/List/unzip-    dhall-lang/Prelude/Location/package.dhall     dhall-lang/Prelude/Location/Type+    dhall-lang/Prelude/Location/package.dhall     dhall-lang/Prelude/Map/Entry+    dhall-lang/Prelude/Map/Type     dhall-lang/Prelude/Map/empty-    dhall-lang/Prelude/Map/keys     dhall-lang/Prelude/Map/keyText     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/Type     dhall-lang/Prelude/Map/values     dhall-lang/Prelude/Monoid     dhall-lang/Prelude/Natural/build@@ -100,10 +120,15 @@     dhall-lang/Prelude/Natural/isZero     dhall-lang/Prelude/Natural/lessThan     dhall-lang/Prelude/Natural/lessThanEqual+    dhall-lang/Prelude/Natural/listMax+    dhall-lang/Prelude/Natural/listMin+    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     dhall-lang/Prelude/Natural/subtract     dhall-lang/Prelude/Natural/sum     dhall-lang/Prelude/Natural/toDouble@@ -123,7 +148,6 @@     dhall-lang/Prelude/Optional/package.dhall     dhall-lang/Prelude/Optional/toList     dhall-lang/Prelude/Optional/unzip-    dhall-lang/Prelude/package.dhall     dhall-lang/Prelude/Text/concat     dhall-lang/Prelude/Text/concatMap     dhall-lang/Prelude/Text/concatMapSep@@ -132,6 +156,7 @@     dhall-lang/Prelude/Text/defaultMap     dhall-lang/Prelude/Text/package.dhall     dhall-lang/Prelude/Text/show+    dhall-lang/Prelude/XML/Type     dhall-lang/Prelude/XML/attribute     dhall-lang/Prelude/XML/element     dhall-lang/Prelude/XML/emptyAttributes@@ -139,7 +164,7 @@     dhall-lang/Prelude/XML/package.dhall     dhall-lang/Prelude/XML/render     dhall-lang/Prelude/XML/text-    dhall-lang/Prelude/XML/Type+    dhall-lang/Prelude/package.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@@ -396,6 +421,7 @@         aeson                       >= 1.0.0.0  && < 1.5 ,         aeson-pretty                               < 0.9 ,         ansi-terminal               >= 0.6.3.1  && < 0.11,+        atomic-write                >= 0.2.0.7  && < 0.3 ,         bytestring                                 < 0.11,         case-insensitive                           < 1.3 ,         cborg                       >= 0.2.0.0  && < 0.3 ,@@ -411,16 +437,17 @@         exceptions                  >= 0.8.3    && < 0.11,         filepath                    >= 1.4      && < 1.5 ,         haskeline                   >= 0.7.2.1  && < 0.8 ,-        hashable                    >= 1.2      && < 1.3 ,+        hashable                    >= 1.2      && < 1.4 ,         lens-family-core            >= 1.0.0    && < 2.1 ,-        megaparsec                  >= 6.5.0    && < 7.1 ,+        megaparsec                  >= 7        && < 8.1 ,         memory                      >= 0.14     && < 0.16,         mtl                         >= 2.2.1    && < 2.3 ,         network-uri                 >= 2.6      && < 2.7 ,         optparse-applicative        >= 0.14.0.0 && < 0.16,         parsers                     >= 0.12.4   && < 0.13,-        prettyprinter               >= 1.2.0.1  && < 1.4 ,+        prettyprinter               >= 1.5.1    && < 1.6 ,         prettyprinter-ansi-terminal >= 1.1.1    && < 1.2 ,+        pretty-simple                              < 4   ,         profunctors                 >= 3.1.2    && < 5.6 ,         repline                     >= 0.2.1.0  && < 0.3 ,         serialise                   >= 0.2.0.0  && < 0.3 ,@@ -484,47 +511,49 @@             TemplateHaskell      Exposed-Modules:-        Dhall,-        Dhall.Binary,-        Dhall.Context,-        Dhall.Core,-        Dhall.Crypto,-        Dhall.Diff,-        Dhall.Tags,-        Dhall.Format,-        Dhall.Freeze,-        Dhall.Import,-        Dhall.Lint,-        Dhall.Main,-        Dhall.Map,-        Dhall.Optics,-        Dhall.Set,-        Dhall.Src,-        Dhall.Parser,-        Dhall.Parser.Expression,-        Dhall.Parser.Token,-        Dhall.Pretty,-        Dhall.Repl,-        Dhall.Tutorial,-        Dhall.TypeCheck,+        Dhall+        Dhall.Binary+        Dhall.Context+        Dhall.Core+        Dhall.Crypto+        Dhall.Diff+        Dhall.Format+        Dhall.Freeze+        Dhall.Import+        Dhall.Lint+        Dhall.Main+        Dhall.Map+        Dhall.Optics+        Dhall.Parser+        Dhall.Parser.Expression+        Dhall.Parser.Token+        Dhall.Pretty+        Dhall.Repl+        Dhall.Set+        Dhall.Src+        Dhall.Tags+        Dhall.Tutorial+        Dhall.TypeCheck         Dhall.Util         Dhall.Version     if !flag(cross)         Exposed-Modules:             Dhall.TH     Other-Modules:-        Dhall.Pretty.Internal,-        Dhall.Parser.Combinators,-        Dhall.URL,-        Dhall.Import.Types,-        Dhall.Syntax,-        Dhall.Eval,+        Dhall.Eval+        Dhall.Import.Types+        Dhall.Normalize+        Dhall.Parser.Combinators+        Dhall.Pretty.Internal+        Dhall.Syntax+        Dhall.URL         Paths_dhall     Autogen-Modules:         Paths_dhall     if flag(with-http)       Other-Modules:         Dhall.Import.HTTP+        Dhall.Import.Manager      GHC-Options: -Wall -fwarn-incomplete-uni-patterns     Default-Language: Haskell2010
doctest/Main.hs view
@@ -27,10 +27,17 @@         Test.DocTest.doctest             [ "-DWITH_HTTP"             , "--fast"+            , prefix </> "ghc-src"++            -- Unfortunately we cannot target the entire @src@ directory.+            -- The reason is that src/Dhall/Version.hs depends on+            -- the generated Paths_dhall module which is "out-of-scope"+            -- when running the testsuite with cabal v1-test.+            -- Instead, we target a selection of modules whose combined module+            -- dependency tree covers all modules that contain doctests.++            -- , prefix </> "src"             , "-i" <> (prefix </> "src")-            , "-i" <> (prefix </> "ghc-src")-            , prefix </> "src/Dhall.hs"-            , prefix </> "src/Dhall/Import.hs"-            , prefix </> "src/Dhall/Tutorial.hs"             , prefix </> "src/Dhall/Tags.hs"+            , prefix </> "src/Dhall/Tutorial.hs"             ]
ghc-src/Dhall/Import/HTTP.hs view
@@ -2,7 +2,9 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards   #-} -module Dhall.Import.HTTP where+module Dhall.Import.HTTP+    ( fetchFromHttpUrl+    ) where  import Control.Exception (Exception) import Control.Monad.IO.Class (MonadIO(..))@@ -169,18 +171,28 @@         <>  show e' <> "\n" #endif -newManager :: IO Manager+newManager :: StateT Status IO Manager newManager = do     let settings = HTTP.tlsManagerSettings-#ifdef MIN_VERSION_http_client #if MIN_VERSION_http_client(0,5,0)           { HTTP.managerResponseTimeout = HTTP.responseTimeoutMicro (30 * 1000 * 1000) }  -- 30 seconds #else           { HTTP.managerResponseTimeout = Just (30 * 1000 * 1000) }  -- 30 seconds #endif-#endif-    HTTP.newManager settings +    Status { _manager = oldManager, ..} <- State.get++    case oldManager of+        Nothing -> do+            manager <- liftIO (HTTP.newManager settings)++            State.put (Status { _manager = Just manager , ..})++            return manager++        Just manager -> do+            return manager+ data NotCORSCompliant = NotCORSCompliant     { expectedOrigins :: [ByteString]     , actualOrigin    :: ByteString@@ -260,7 +272,7 @@  fetchFromHttpUrl :: URL -> Maybe [HTTPHeader] -> StateT Status IO Text.Text fetchFromHttpUrl childURL mheaders = do-    manager <- liftIO $ newManager+    manager <- newManager      let childURLString = Text.unpack (renderURL childURL) 
+ ghc-src/Dhall/Import/Manager.hs view
@@ -0,0 +1,14 @@+{-| Both the GHC and GHCJS implementations of "Dhall.Import.Manager" export a+    `Manager` type suitable for use within the "Dhall.Import" module++    For the GHC implementation the `Manager` type is a real `Manager` from the+    @http-client@ package.  For the GHCJS implementation the `Manager` type is+    a synonym for @`Data.Void.Void`@ since GHCJS does not use a `Manager` for+    HTTP requests.+-}+module Dhall.Import.Manager+    ( -- * Manager+      Manager+    ) where++import Network.HTTP.Client (Manager)
ghcjs-src/Dhall/Import/HTTP.hs view
@@ -1,7 +1,10 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards   #-} -module Dhall.Import.HTTP where+module Dhall.Import.HTTP+    ( fetchFromHttpUrl+    , Manager+    ) where  import Control.Monad.IO.Class (MonadIO(..)) import Control.Monad.Trans.State.Strict (StateT)@@ -12,9 +15,18 @@ import qualified Data.Text as Text import qualified JavaScript.XHR +import Data.Void (Void) import Dhall.Core (URL(..)) import Dhall.URL (renderURL) import Dhall.Import.Types++{-| The GHCJS implementation does not require a `Manager`++    The purpose of this synonym is so that "Dhall.Import.Types" can import a+    `Manager` type from "Dhall.Import.HTTP" that does the correct thing for+    both the GHC and GHCJS implementations+-}+type Manager = Void  fetchFromHttpUrl     :: URL
+ ghcjs-src/Dhall/Import/Manager.hs view
@@ -0,0 +1,17 @@+{-| Both the GHC and GHCJS implementations of "Dhall.Import.Manager" export a+    `Manager` type suitable for use within the "Dhall.Import" module++    For the GHC implementation the `Manager` type is a real `Manager` from the+    @http-client@ package.  For the GHCJS implementation the `Manager` type is+    a synonym for @`Data.Void.Void`@ since GHCJS does not use a `Manager` for+    HTTP requests.+-}+module Dhall.Import.Manager+    ( -- * Manager+      Manager+    ) where++import Data.Void (Void)++-- | GHCJS does not use a `Manager`+type Manager = Void
src/Dhall.hs view
@@ -41,14 +41,14 @@     , HasEvaluateSettings     , detailed -    -- * Types-    , Type (..)-    , RecordType(..)-    , UnionType(..)-    , InputType(..)+    -- * Decoders+    , Decoder (..)+    , RecordDecoder(..)+    , UnionDecoder(..)+    , Encoder(..)     , FromDhall(..)     , Interpret-    , InvalidType(..)+    , InvalidDecoder(..)     , ExtractErrors(..)     , Extractor     , MonadicExtractor@@ -72,6 +72,7 @@     , sequence     , list     , vector+    , function     , setFromDistinctList     , setIgnoringDuplicates     , hashSetFromDistinctList@@ -94,14 +95,14 @@     , Inject     , inject     , genericToDhall-    , RecordInputType(..)-    , inputFieldWith-    , inputField-    , inputRecord-    , UnionInputType(..)-    , inputConstructorWith-    , inputConstructor-    , inputUnion+    , RecordEncoder(..)+    , encodeFieldWith+    , encodeField+    , recordEncoder+    , UnionEncoder(..)+    , encodeConstructorWith+    , encodeConstructor+    , unionEncoder     , (>|<)      -- * Miscellaneous@@ -140,7 +141,7 @@ import Data.Vector (Vector) import Data.Void (Void) import Data.Word (Word8, Word16, Word32, Word64)-import Dhall.Core (Expr(..), Chunks(..), DhallDouble(..))+import Dhall.Syntax (Expr(..), Chunks(..), DhallDouble(..)) import Dhall.Import (Imported(..)) import Dhall.Parser (Src(..)) import Dhall.TypeCheck (DetailedTypeError(..), TypeError)@@ -202,7 +203,7 @@ -} typeError :: Expr s a -> Expr s a -> Extractor s a b typeError expected actual =-    Failure . ExtractErrors . pure . TypeMismatch $ InvalidType expected actual+    Failure . ExtractErrors . pure . TypeMismatch $ InvalidDecoder expected actual  -- | Turn a `Text` message into an extraction failure extractError :: Text -> Extractor s a b@@ -240,7 +241,7 @@     a term-level error, described with a freeform text value. -} data ExtractError s a =-    TypeMismatch (InvalidType s a)+    TypeMismatch (InvalidDecoder s a)   | ExtractError Text  instance (Pretty s, Pretty a, Typeable s, Typeable a) => Show (ExtractError s a) where@@ -256,32 +257,32 @@  instance (Pretty s, Pretty a, Typeable s, Typeable a) => Exception (ExtractError s a) -{-| Every `Type` must obey the contract that if an expression's type matches the+{-| Every `Decoder` must obey the contract that if an expression's type matches the     the `expected` type then the `extract` function must not fail with a type error.     If not, then this value is returned. -    This value indicates that an invalid `Type` was provided to the `input`+    This value indicates that an invalid `Decoder` was provided to the `input`     function -}-data InvalidType s a = InvalidType-  { invalidTypeExpected   :: Expr s a-  , invalidTypeExpression :: Expr s a+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 (InvalidType s a)+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 (InvalidType s a) where-    show InvalidType { .. } =-        _ERROR <> ": Invalid Dhall.Type                                                  \n\+instance (Pretty s, Pretty a, Typeable s, Typeable a) => Show (InvalidDecoder s a) where+    show InvalidDecoder { .. } =+        _ERROR <> ": Invalid Dhall.Decoder                                               \n\         \                                                                                \n\-        \Every Type must provide an extract function that succeeds if an expression      \n\-        \matches the expected type.  You provided a Type that disobeys this contract     \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 Type provided has the expected dhall type:                                  \n\+        \The Decoder provided has the expected dhall type:                               \n\         \                                                                                \n\         \" <> show txt0 <> "\n\         \                                                                                \n\@@ -290,8 +291,8 @@         \" <> show txt1 <> "\n\         \                                                                                \n"         where-          txt0 = Dhall.Util.insert invalidTypeExpected-          txt1 = Dhall.Util.insert invalidTypeExpression+          txt0 = Dhall.Util.insert invalidDecoderExpected+          txt1 = Dhall.Util.insert invalidDecoderExpression  -- | @since 1.16 data InputSettings = InputSettings@@ -403,8 +404,8 @@     This uses the settings from 'defaultInputSettings'. -} input-    :: Type a-    -- ^ The type of value to decode from Dhall to Haskell+    :: Decoder a+    -- ^ The decoder for the Dhall value     -> Text     -- ^ The Dhall program     -> IO a@@ -420,13 +421,13 @@ -} inputWithSettings     :: InputSettings-    -> Type a-    -- ^ The type of value to decode from Dhall to Haskell+    -> Decoder a+    -- ^ The decoder for the Dhall value     -> Text     -- ^ The Dhall program     -> IO a     -- ^ The decoded value in Haskell-inputWithSettings settings (Type {..}) txt = do+inputWithSettings settings (Decoder {..}) txt = do     expr  <- Dhall.Core.throws (Dhall.Parser.exprFromText (view sourceName settings) txt)      let InputSettings {..} = settings@@ -464,8 +465,8 @@     @since 1.16 -} inputFile-  :: Type a-  -- ^ The type of value to decode from Dhall to Haskell+  :: Decoder a+  -- ^ The decoder for the Dhall value   -> FilePath   -- ^ The path to the Dhall program.   -> IO a@@ -480,8 +481,8 @@ -} inputFileWithSettings   :: EvaluateSettings-  -> Type a-  -- ^ The type of value to decode from Dhall to Haskell+  -> Decoder a+  -- ^ The decoder for the Dhall value   -> FilePath   -- ^ The path to the Dhall program.   -> IO a@@ -546,13 +547,13 @@ --   a much better user experience. rawInput     :: Alternative f-    => Type a-    -- ^ The type of value to decode from Dhall to Haskell+    => 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 (Type {..}) expr = do+rawInput (Decoder {..}) expr = do     case extract (Dhall.Core.normalize expr) of         Success x  -> pure x         Failure _e -> empty@@ -672,24 +673,24 @@     handler1 :: TypeError Src Void -> IO a     handler1 e = Control.Exception.throwIO (DetailedTypeError e) -{-| A @(Type a)@ represents a way to marshal a value of type @\'a\'@ from Dhall+{-| A @(Decoder a)@ represents a way to marshal a value of type @\'a\'@ from Dhall     into Haskell -    You can produce `Type`s either explicitly:+    You can produce `Decoder`s either explicitly: -> example :: Type (Vector Text)+> example :: Decoder (Vector Text) > example = vector text      ... or implicitly using `auto`: -> example :: Type (Vector Text)+> example :: Decoder (Vector Text) > example = auto -    You can consume `Type`s using the `input` function:+    You can consume `Decoder`s using the `input` function: -> input :: Type a -> Text -> IO a+> input :: Decoder a -> Text -> IO a -}-data Type a = Type+data Decoder a = Decoder     { extract  :: Expr Src Void -> Extractor Src Void a     -- ^ Extracts Haskell value from the Dhall expression     , expected :: Expr Src Void@@ -702,8 +703,8 @@ >>> input bool "True" True -}-bool :: Type Bool-bool = Type {..}+bool :: Decoder Bool+bool = Decoder {..}   where     extract (BoolLit b) = pure b     extract expr        = typeError expected expr@@ -715,8 +716,8 @@ >>> input natural "42" 42 -}-natural :: Type Natural-natural = Type {..}+natural :: Decoder Natural+natural = Decoder {..}   where     extract (NaturalLit n) = pure n     extract  expr             = typeError Natural expr@@ -728,8 +729,8 @@ >>> input integer "+42" 42 -}-integer :: Type Integer-integer = Type {..}+integer :: Decoder Integer+integer = Decoder {..}   where     extract (IntegerLit n) = pure n     extract  expr          = typeError Integer expr@@ -741,7 +742,7 @@ >>> input scientific "1e100" 1.0e100 -}-scientific :: Type Scientific+scientific :: Decoder Scientific scientific = fmap Data.Scientific.fromFloatDigits double  {-| Decode a `Double`@@ -749,8 +750,8 @@ >>> input double "42.0" 42.0 -}-double :: Type Double-double = Type {..}+double :: Decoder Double+double = Decoder {..}   where     extract (DoubleLit (DhallDouble n)) = pure n     extract  expr                       = typeError Double expr@@ -762,7 +763,7 @@ >>> input lazyText "\"Test\"" "Test" -}-lazyText :: Type Data.Text.Lazy.Text+lazyText :: Decoder Data.Text.Lazy.Text lazyText = fmap Data.Text.Lazy.fromStrict strictText  {-| Decode strict `Text`@@ -770,8 +771,8 @@ >>> input strictText "\"Test\"" "Test" -}-strictText :: Type Text-strictText = Type {..}+strictText :: Decoder Text+strictText = Decoder {..}   where     extract (TextLit (Chunks [] t)) = pure t     extract  expr = typeError Text expr@@ -782,8 +783,8 @@ >>> input (maybe natural) "Some 1" Just 1 -}-maybe :: Type a -> Type (Maybe a)-maybe (Type extractIn expectedIn) = Type extractOut expectedOut+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@@ -796,8 +797,8 @@ >>> input (sequence natural) "[1, 2, 3]" fromList [1,2,3] -}-sequence :: Type a -> Type (Seq a)-sequence (Type extractIn expectedIn) = Type extractOut expectedOut+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@@ -809,7 +810,7 @@ >>> input (list natural) "[1, 2, 3]" [1,2,3] -}-list :: Type a -> Type [a]+list :: Decoder a -> Decoder [a] list = fmap Data.Foldable.toList . sequence  {-| Decode a `Vector`@@ -817,9 +818,33 @@ >>> input (vector natural) "[1, 2, 3]" [1,2,3] -}-vector :: Type a -> Type (Vector a)+vector :: Decoder a -> Decoder (Vector a) vector = fmap Data.Vector.fromList . list +{-| Decode a Dhall function into a Haskell function++>>> f <- input (function defaultInterpretOptions inject bool) "Natural/even" :: IO (Natural -> Bool)+>>> f 0+True+>>> f 1+False+-}+function+    :: InterpretOptions+    -> Encoder a+    -> Decoder b+    -> Decoder (a -> b)+function options (Encoder {..}) (Decoder extractIn expectedIn) =+    Decoder extractOut expectedOut+  where+    normalizer_ = Just (inputNormalizer options)++    extractOut e = pure (\i -> case extractIn (Dhall.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 `Set` from a `List`  >>> input (setIgnoringDuplicates natural) "[1, 2, 3]"@@ -831,7 +856,7 @@ fromList [1,3]  -}-setIgnoringDuplicates :: (Ord a) => Type a -> Type (Data.Set.Set a)+setIgnoringDuplicates :: (Ord a) => Decoder a -> Decoder (Data.Set.Set a) setIgnoringDuplicates = fmap Data.Set.fromList . list  {-| Decode a `HashSet` from a `List`@@ -846,8 +871,8 @@  -} hashSetIgnoringDuplicates :: (Hashable a, Ord a)-                          => Type a-                          -> Type (Data.HashSet.HashSet a)+                          => Decoder a+                          -> Decoder (Data.HashSet.HashSet a) hashSetIgnoringDuplicates = fmap Data.HashSet.fromList . list  {-| Decode a `Set` from a `List` with distinct elements@@ -876,7 +901,7 @@ >  -}-setFromDistinctList :: (Ord a, Show a) => Type a -> Type (Data.Set.Set a)+setFromDistinctList :: (Ord a, Show a) => Decoder a -> Decoder (Data.Set.Set a) setFromDistinctList = setHelper Data.Set.size Data.Set.fromList  {-| Decode a `HashSet` from a `List` with distinct elements@@ -906,17 +931,17 @@  -} hashSetFromDistinctList :: (Hashable a, Ord a, Show a)-                        => Type a-                        -> Type (Data.HashSet.HashSet 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)-          -> Type a-          -> Type (t a)-setHelper size toSet (Type extractIn expectedIn) = Type extractOut expectedOut+          -> 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@@ -954,7 +979,7 @@ fromList [(1,False)]  -}-map :: Ord k => Type k -> Type v -> Type (Map k v)+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@@@ -971,7 +996,7 @@ fromList [(1,False)]  -}-hashMap :: (Eq k, Hashable k) => Type k -> Type v -> Type (HashMap k v)+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@@ -979,8 +1004,8 @@ >>> input (pairFromMapEntry strictText natural) "{ mapKey = \"foo\", mapValue = 3 }" ("foo",3) -}-pairFromMapEntry :: Type k -> Type v -> Type (k, v)-pairFromMapEntry k v = Type extractOut expectedOut+pairFromMapEntry :: Decoder k -> Decoder v -> Decoder (k, v)+pairFromMapEntry k v = Decoder extractOut expectedOut   where     extractOut (RecordLit kvs)         | Just key <- Dhall.Map.lookup "mapKey" kvs@@ -995,8 +1020,8 @@ >>> input unit "{=}"  -- GHC doesn't print the result if it is ()  -}-unit :: Type ()-unit = Type extractOut expectedOut+unit :: Decoder ()+unit = Decoder extractOut expectedOut   where     extractOut (RecordLit fields)         | Data.Foldable.null fields = pure ()@@ -1008,7 +1033,7 @@  Since @<>@ is uninhabited, @'input' 'void'@ will always fail. -}-void :: Type Void+void :: Decoder Void void = union mempty  {-| Decode a `String`@@ -1017,16 +1042,16 @@ "ABC"  -}-string :: Type String+string :: Decoder String string = Data.Text.Lazy.unpack <$> lazyText -{-| Given a pair of `Type`s, decode a tuple-record into their pairing.+{-| Given a pair of `Decoder`s, decode a tuple-record into their pairing.  >>> input (pair natural bool) "{ _1 = 42, _2 = False }" (42,False) -}-pair :: Type a -> Type b -> Type (a, b)-pair l r = Type extractOut expectedOut+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) $ Dhall.Map.lookup "_1" fields)@@ -1054,9 +1079,9 @@     types. -} class FromDhall a where-    autoWith:: InterpretOptions -> Type a+    autoWith:: InterpretOptions -> Decoder a     default autoWith-        :: (Generic a, GenericFromDhall (Rep a)) => InterpretOptions -> Type a+        :: (Generic a, GenericFromDhall (Rep a)) => InterpretOptions -> Decoder a     autoWith options = fmap GHC.Generics.to (evalState (genericAutoWith options) 1)  {-| A compatibility alias for `FromDhall`@@ -1126,20 +1151,8 @@     autoWith opts = Dhall.hashMap (autoWith opts) (autoWith opts)  instance (ToDhall a, FromDhall b) => FromDhall (a -> b) where-    autoWith opts = Type extractOut expectedOut-      where-        normalizer_ = Just (inputNormalizer opts)--        -- ToDo-        extractOut e = pure (\i -> case extractIn (Dhall.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--        InputType {..} = injectWith opts--        Type extractIn expectedIn = autoWith opts+    autoWith opts =+        function opts (injectWith opts) (autoWith opts)  instance (FromDhall a, FromDhall b) => FromDhall (a, b) @@ -1147,7 +1160,7 @@  > auto = autoWith defaultInterpretOptions -}-auto :: FromDhall a => Type a+auto :: FromDhall a => Decoder a auto = autoWith defaultInterpretOptions  {-| This type is exactly the same as `Data.Fix.Fix` except with a different@@ -1160,7 +1173,7 @@ resultToFix (Result x) = Fix (fmap resultToFix x)  instance FromDhall (f (Result f)) => FromDhall (Result f) where-    autoWith options = Type { expected = expected_, extract = extract_ }+    autoWith options = Decoder { expected = expected_, extract = extract_ }       where         expected_ = "result" @@ -1244,11 +1257,11 @@ -- > -- >     print (convert x :: Expr) instance (Functor f, FromDhall (f (Result f))) => FromDhall (Fix f) where-    autoWith options = Type { expected = expected_, extract = extract_ }+    autoWith options = Decoder { expected = expected_, extract = extract_ }       where         expected_ =             Pi "result" (Const Dhall.Core.Type)-                (Pi "Make" (Pi "_" (expected (autoWith options :: Type (f (Result f)))) "result")+                (Pi "Make" (Pi "_" (expected (autoWith options :: Decoder (f (Result f)))) "result")                     "result"                 ) @@ -1263,7 +1276,7 @@     having to explicitly provide a `FromDhall` instance for a type as long as     the type derives `Generic` -}-genericAuto :: (Generic a, GenericFromDhall (Rep a)) => Type a+genericAuto :: (Generic a, GenericFromDhall (Rep a)) => Decoder a genericAuto = fmap to (evalState (genericAutoWith defaultInterpretOptions) 1)  {-| Use these options to tweak how Dhall derives a generic implementation of@@ -1330,7 +1343,7 @@     for automatically deriving a generic implementation -} class GenericFromDhall f where-    genericAutoWith :: InterpretOptions -> State Int (Type (f a))+    genericAutoWith :: InterpretOptions -> State Int (Decoder (f a))  instance GenericFromDhall f => GenericFromDhall (M1 D d f) where     genericAutoWith options = do@@ -1338,7 +1351,7 @@         pure (fmap M1 res)  instance GenericFromDhall V1 where-    genericAutoWith _ = pure Type {..}+    genericAutoWith _ = pure Decoder {..}       where         extract expr = typeError expected expr @@ -1399,7 +1412,7 @@   empty  instance (Constructor c1, Constructor c2, GenericFromDhall f1, GenericFromDhall f2) => GenericFromDhall (M1 C c1 f1 :+: M1 C c2 f2) where-    genericAutoWith options@(InterpretOptions {..}) = pure (Type {..})+    genericAutoWith options@(InterpretOptions {..}) = pure (Decoder {..})       where         nL :: M1 i c1 f1 a         nL = undefined@@ -1427,11 +1440,11 @@                     ]                 ) -        Type extractL expectedL = evalState (genericAutoWith options) 1-        Type extractR expectedR = evalState (genericAutoWith options) 1+        Decoder extractL expectedL = evalState (genericAutoWith options) 1+        Decoder extractR expectedR = evalState (genericAutoWith options) 1  instance (Constructor c, GenericFromDhall (f :+: g), GenericFromDhall h) => GenericFromDhall ((f :+: g) :+: M1 C c h) where-    genericAutoWith options@(InterpretOptions {..}) = pure (Type {..})+    genericAutoWith options@(InterpretOptions {..}) = pure (Decoder {..})       where         n :: M1 i c h a         n = undefined@@ -1448,13 +1461,13 @@         expected =             Union (Dhall.Map.insert name (notEmptyRecord expectedR) ktsL) -        Type extractL expectedL = evalState (genericAutoWith options) 1-        Type extractR expectedR = evalState (genericAutoWith options) 1+        Decoder extractL expectedL = evalState (genericAutoWith options) 1+        Decoder extractR expectedR = evalState (genericAutoWith options) 1          ktsL = unsafeExpectUnion "genericAutoWith (:+:)" expectedL  instance (Constructor c, GenericFromDhall f, GenericFromDhall (g :+: h)) => GenericFromDhall (M1 C c f :+: (g :+: h)) where-    genericAutoWith options@(InterpretOptions {..}) = pure (Type {..})+    genericAutoWith options@(InterpretOptions {..}) = pure (Decoder {..})       where         n :: M1 i c f a         n = undefined@@ -1471,20 +1484,20 @@         expected =             Union (Dhall.Map.insert name (notEmptyRecord expectedL) ktsR) -        Type extractL expectedL = evalState (genericAutoWith options) 1-        Type extractR expectedR = evalState (genericAutoWith options) 1+        Decoder extractL expectedL = evalState (genericAutoWith options) 1+        Decoder extractR expectedR = evalState (genericAutoWith options) 1          ktsR = unsafeExpectUnion "genericAutoWith (:+:)" expectedR  instance (GenericFromDhall (f :+: g), GenericFromDhall (h :+: i)) => GenericFromDhall ((f :+: g) :+: (h :+: i)) where-    genericAutoWith options = pure (Type {..})+    genericAutoWith options = pure (Decoder {..})       where         extract e = fmap L1 (extractL e) `ealt` fmap R1 (extractR e)          expected = Union (Dhall.Map.union ktsL ktsR) -        Type extractL expectedL = evalState (genericAutoWith options) 1-        Type extractR expectedR = evalState (genericAutoWith options) 1+        Decoder extractL expectedL = evalState (genericAutoWith options) 1+        Decoder extractR expectedR = evalState (genericAutoWith options) 1          ktsL = unsafeExpectUnion "genericAutoWith (:+:)" expectedL         ktsR = unsafeExpectUnion "genericAutoWith (:+:)" expectedR@@ -1495,7 +1508,7 @@         pure (fmap M1 res)  instance GenericFromDhall U1 where-    genericAutoWith _ = pure (Type {..})+    genericAutoWith _ = pure (Decoder {..})       where         extract _ = pure U1 @@ -1510,8 +1523,8 @@  instance (GenericFromDhall (f :*: g), GenericFromDhall (h :*: i)) => GenericFromDhall ((f :*: g) :*: (h :*: i)) where     genericAutoWith options = do-        Type extractL expectedL <- genericAutoWith options-        Type extractR expectedR <- genericAutoWith options+        Decoder extractL expectedL <- genericAutoWith options+        Decoder extractR expectedR <- genericAutoWith options          let ktsL = unsafeExpectRecord "genericAutoWith (:*:)" expectedL         let ktsR = unsafeExpectRecord "genericAutoWith (:*:)" expectedR@@ -1521,7 +1534,7 @@         let extract expression =                 liftA2 (:*:) (extractL expression) (extractR expression) -        return (Type {..})+        return (Decoder {..})  instance (GenericFromDhall (f :*: g), Selector s, FromDhall a) => GenericFromDhall ((f :*: g) :*: M1 S s (K1 i a)) where     genericAutoWith options@InterpretOptions{..} = do@@ -1530,9 +1543,9 @@          nameR <- fmap fieldModifier (getSelName nR) -        Type extractL expectedL <- genericAutoWith options+        Decoder extractL expectedL <- genericAutoWith options -        let Type extractR expectedR = autoWith options+        let Decoder extractR expectedR = autoWith options          let ktsL = unsafeExpectRecord "genericAutoWith (:*:)" expectedL @@ -1551,7 +1564,7 @@                             _ -> die                     _ -> die -        return (Type {..})+        return (Decoder {..})  instance (Selector s, FromDhall a, GenericFromDhall (f :*: g)) => GenericFromDhall (M1 S s (K1 i a) :*: (f :*: g)) where     genericAutoWith options@InterpretOptions{..} = do@@ -1560,9 +1573,9 @@          nameL <- fmap fieldModifier (getSelName nL) -        let Type extractL expectedL = autoWith options+        let Decoder extractL expectedL = autoWith options -        Type extractR expectedR <- genericAutoWith options+        Decoder extractR expectedR <- genericAutoWith options          let ktsR = unsafeExpectRecord "genericAutoWith (:*:)" expectedR @@ -1581,7 +1594,7 @@                             _ -> die                     _ -> die -        return (Type {..})+        return (Decoder {..})  instance (Selector s1, Selector s2, FromDhall a1, FromDhall a2) => GenericFromDhall (M1 S s1 (K1 i1 a1) :*: M1 S s2 (K1 i2 a2)) where     genericAutoWith options@InterpretOptions{..} = do@@ -1594,8 +1607,8 @@         nameL <- fmap fieldModifier (getSelName nL)         nameR <- fmap fieldModifier (getSelName nR) -        let Type extractL expectedL = autoWith options-        let Type extractR expectedR = autoWith options+        let Decoder extractL expectedL = autoWith options+        let Decoder extractR expectedR = autoWith options          let expected =                 Record@@ -1618,7 +1631,7 @@                             Nothing -> die                     _ -> die -        return (Type {..})+        return (Decoder {..})  instance (Selector s, FromDhall a) => GenericFromDhall (M1 S s (K1 i a)) where     genericAutoWith options@InterpretOptions{..} = do@@ -1627,7 +1640,7 @@          name <- fmap fieldModifier (getSelName n) -        let Type { extract = extract', expected = expected'} = autoWith options+        let Decoder { extract = extract', expected = expected'} = autoWith options          let expected =                 case singletonConstructors of@@ -1660,20 +1673,20 @@                     Smart | selName n == "" -> extract0                     _                       -> extract1 -        return (Type {..})+        return (Decoder {..}) -{-| An @(InputType a)@ represents a way to marshal a value of type @\'a\'@ from+{-| An @(Encoder a)@ represents a way to marshal a value of type @\'a\'@ from     Haskell into Dhall -}-data InputType a = InputType+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 InputType where-    contramap f (InputType embed declared) = InputType embed' declared+instance Contravariant Encoder where+    contramap f (Encoder embed declared) = Encoder embed' declared       where         embed' x = embed (f x) @@ -1692,9 +1705,9 @@     * Marshaling the resulting Dhall expression back into a Haskell value -} class ToDhall a where-    injectWith :: InterpretOptions -> InputType a+    injectWith :: InterpretOptions -> Encoder a     default injectWith-        :: (Generic a, GenericToDhall (Rep a)) => InterpretOptions -> InputType a+        :: (Generic a, GenericToDhall (Rep a)) => InterpretOptions -> Encoder a     injectWith options         = contramap GHC.Generics.from (evalState (genericToDhallWith options) 1) @@ -1708,7 +1721,7 @@  > inject = injectWith defaultInterpretOptions -}-inject :: ToDhall a => InputType a+inject :: ToDhall a => Encoder a inject = injectWith defaultInterpretOptions  {-| Use the default options for injecting a value, whose structure is@@ -1718,26 +1731,26 @@ want to define orphan instances for. -} genericToDhall-  :: (Generic a, GenericToDhall (Rep a)) => InputType a+  :: (Generic a, GenericToDhall (Rep a)) => Encoder a genericToDhall     = contramap GHC.Generics.from (evalState (genericToDhallWith defaultInterpretOptions) 1)  instance ToDhall Void where-    injectWith _ = InputType {..}+    injectWith _ = Encoder {..}       where         embed = Data.Void.absurd          declared = Union mempty  instance ToDhall Bool where-    injectWith _ = InputType {..}+    injectWith _ = Encoder {..}       where         embed = BoolLit          declared = Bool  instance ToDhall Data.Text.Lazy.Text where-    injectWith _ = InputType {..}+    injectWith _ = Encoder {..}       where         embed text =             TextLit (Chunks [] (Data.Text.Lazy.toStrict text))@@ -1745,7 +1758,7 @@         declared = Text  instance ToDhall Text where-    injectWith _ = InputType {..}+    injectWith _ = Encoder {..}       where         embed text = TextLit (Chunks [] text) @@ -1753,24 +1766,24 @@  instance {-# OVERLAPS #-} ToDhall String where     injectWith options =-        contramap Data.Text.pack (injectWith options :: InputType Text)+        contramap Data.Text.pack (injectWith options :: Encoder Text)  instance ToDhall Natural where-    injectWith _ = InputType {..}+    injectWith _ = Encoder {..}       where         embed = NaturalLit          declared = Natural  instance ToDhall Integer where-    injectWith _ = InputType {..}+    injectWith _ = Encoder {..}       where         embed = IntegerLit          declared = Integer  instance ToDhall Int where-    injectWith _ = InputType {..}+    injectWith _ = Encoder {..}       where         embed = IntegerLit . toInteger @@ -1783,7 +1796,7 @@ -}  instance ToDhall Word where-    injectWith _ = InputType {..}+    injectWith _ = Encoder {..}       where         embed = NaturalLit . fromIntegral @@ -1796,7 +1809,7 @@ -}  instance ToDhall Word8 where-    injectWith _ = InputType {..}+    injectWith _ = Encoder {..}       where         embed = NaturalLit . fromIntegral @@ -1809,7 +1822,7 @@ -}  instance ToDhall Word16 where-    injectWith _ = InputType {..}+    injectWith _ = Encoder {..}       where         embed = NaturalLit . fromIntegral @@ -1822,7 +1835,7 @@ -}  instance ToDhall Word32 where-    injectWith _ = InputType {..}+    injectWith _ = Encoder {..}       where         embed = NaturalLit . fromIntegral @@ -1835,14 +1848,14 @@ -}  instance ToDhall Word64 where-    injectWith _ = InputType {..}+    injectWith _ = Encoder {..}       where         embed = NaturalLit . fromIntegral          declared = Natural  instance ToDhall Double where-    injectWith _ = InputType {..}+    injectWith _ = Encoder {..}       where         embed = DoubleLit . DhallDouble @@ -1850,27 +1863,27 @@  instance ToDhall Scientific where     injectWith options =-        contramap Data.Scientific.toRealFloat (injectWith options :: InputType Double)+        contramap Data.Scientific.toRealFloat (injectWith options :: Encoder Double)  instance ToDhall () where-    injectWith _ = InputType {..}+    injectWith _ = Encoder {..}       where         embed = const (RecordLit mempty)          declared = Record mempty  instance ToDhall a => ToDhall (Maybe a) where-    injectWith options = InputType embedOut declaredOut+    injectWith options = Encoder embedOut declaredOut       where         embedOut (Just x ) = Some (embedIn x)         embedOut  Nothing  = App None declaredIn -        InputType embedIn declaredIn = injectWith options+        Encoder embedIn declaredIn = injectWith options          declaredOut = App Optional declaredIn  instance ToDhall a => ToDhall (Seq a) where-    injectWith options = InputType embedOut declaredOut+    injectWith options = Encoder embedOut declaredOut       where         embedOut xs = ListLit listType (fmap embedIn xs)           where@@ -1880,7 +1893,7 @@          declaredOut = App List declaredIn -        InputType embedIn declaredIn = injectWith options+        Encoder embedIn declaredIn = injectWith options  instance ToDhall a => ToDhall [a] where     injectWith = fmap (contramap Data.Sequence.fromList) injectWith@@ -1920,7 +1933,7 @@  -} instance (ToDhall k, ToDhall v) => ToDhall (Data.Map.Map k v) where-    injectWith options = InputType embedOut declaredOut+    injectWith options = Encoder embedOut declaredOut       where         embedOut m = ListLit listType (mapEntries m)           where@@ -1935,8 +1948,8 @@         recordPair (k, v) = RecordLit (Dhall.Map.fromList                                 [("mapKey", embedK k), ("mapValue", embedV v)]) -        InputType embedK declaredK = injectWith options-        InputType embedV declaredV = injectWith options+        Encoder embedK declaredK = injectWith options+        Encoder embedV declaredV = injectWith options  {-| Embed a `Data.HashMap` as a @Prelude.Map.Type@ @@ -1948,7 +1961,7 @@  -} instance (ToDhall k, ToDhall v) => ToDhall (HashMap k v) where-    injectWith options = InputType embedOut declaredOut+    injectWith options = Encoder embedOut declaredOut       where         embedOut m = ListLit listType (mapEntries m)           where@@ -1963,14 +1976,14 @@         recordPair (k, v) = RecordLit (Dhall.Map.fromList                                 [("mapKey", embedK k), ("mapValue", embedV v)]) -        InputType embedK declaredK = injectWith options-        InputType embedV declaredV = injectWith options+        Encoder embedK declaredK = injectWith options+        Encoder embedV declaredV = injectWith options  {-| This is the underlying class that powers the `FromDhall` class's support     for automatically deriving a generic implementation -} class GenericToDhall f where-    genericToDhallWith :: InterpretOptions -> State Int (InputType (f a))+    genericToDhallWith :: InterpretOptions -> State Int (Encoder (f a))  instance GenericToDhall f => GenericToDhall (M1 D d f) where     genericToDhallWith options = do@@ -1984,7 +1997,7 @@  instance (Selector s, ToDhall a) => GenericToDhall (M1 S s (K1 i a)) where     genericToDhallWith options@InterpretOptions{..} = do-        let InputType { embed = embed', declared = declared' } =+        let Encoder { embed = embed', declared = declared' } =                 injectWith options          let n :: M1 S s (K1 i a) r@@ -2012,10 +2025,10 @@                     _ ->                         Record (Dhall.Map.singleton name declared') -        return (InputType {..})+        return (Encoder {..})  instance (Constructor c1, Constructor c2, GenericToDhall f1, GenericToDhall f2) => GenericToDhall (M1 C c1 f1 :+: M1 C c2 f2) where-    genericToDhallWith options@(InterpretOptions {..}) = pure (InputType {..})+    genericToDhallWith options@(InterpretOptions {..}) = pure (Encoder {..})       where         embed (L1 (M1 l)) =             case notEmptyRecordLit (embedL l) of@@ -2048,11 +2061,11 @@         keyL = constructorModifier (Data.Text.pack (conName nL))         keyR = constructorModifier (Data.Text.pack (conName nR)) -        InputType embedL declaredL = evalState (genericToDhallWith options) 1-        InputType embedR declaredR = evalState (genericToDhallWith options) 1+        Encoder embedL declaredL = evalState (genericToDhallWith options) 1+        Encoder embedR declaredR = evalState (genericToDhallWith options) 1  instance (Constructor c, GenericToDhall (f :+: g), GenericToDhall h) => GenericToDhall ((f :+: g) :+: M1 C c h) where-    genericToDhallWith options@(InterpretOptions {..}) = pure (InputType {..})+    genericToDhallWith options@(InterpretOptions {..}) = pure (Encoder {..})       where         embed (L1 l) =             case maybeValL of@@ -2073,13 +2086,13 @@          declared = Union (Dhall.Map.insert keyR (notEmptyRecord declaredR) ktsL) -        InputType embedL declaredL = evalState (genericToDhallWith options) 1-        InputType embedR declaredR = evalState (genericToDhallWith options) 1+        Encoder embedL declaredL = evalState (genericToDhallWith options) 1+        Encoder embedR declaredR = evalState (genericToDhallWith options) 1          ktsL = unsafeExpectUnion "genericToDhallWith (:+:)" declaredL  instance (Constructor c, GenericToDhall f, GenericToDhall (g :+: h)) => GenericToDhall (M1 C c f :+: (g :+: h)) where-    genericToDhallWith options@(InterpretOptions {..}) = pure (InputType {..})+    genericToDhallWith options@(InterpretOptions {..}) = pure (Encoder {..})       where         embed (L1 (M1 l)) =             case notEmptyRecordLit (embedL l) of@@ -2100,13 +2113,13 @@          declared = Union (Dhall.Map.insert keyL (notEmptyRecord declaredL) ktsR) -        InputType embedL declaredL = evalState (genericToDhallWith options) 1-        InputType embedR declaredR = evalState (genericToDhallWith options) 1+        Encoder embedL declaredL = evalState (genericToDhallWith options) 1+        Encoder embedR declaredR = evalState (genericToDhallWith options) 1          ktsR = unsafeExpectUnion "genericToDhallWith (:+:)" declaredR  instance (GenericToDhall (f :+: g), GenericToDhall (h :+: i)) => GenericToDhall ((f :+: g) :+: (h :+: i)) where-    genericToDhallWith options = pure (InputType {..})+    genericToDhallWith options = pure (Encoder {..})       where         embed (L1 l) =             case maybeValL of@@ -2125,16 +2138,16 @@          declared = Union (Dhall.Map.union ktsL ktsR) -        InputType embedL declaredL = evalState (genericToDhallWith options) 1-        InputType embedR declaredR = evalState (genericToDhallWith options) 1+        Encoder embedL declaredL = evalState (genericToDhallWith options) 1+        Encoder embedR declaredR = evalState (genericToDhallWith options) 1          ktsL = unsafeExpectUnion "genericToDhallWith (:+:)" declaredL         ktsR = unsafeExpectUnion "genericToDhallWith (:+:)" declaredR  instance (GenericToDhall (f :*: g), GenericToDhall (h :*: i)) => GenericToDhall ((f :*: g) :*: (h :*: i)) where     genericToDhallWith options = do-        InputType embedL declaredL <- genericToDhallWith options-        InputType embedR declaredR <- genericToDhallWith options+        Encoder embedL declaredL <- genericToDhallWith options+        Encoder embedR declaredR <- genericToDhallWith options          let embed (l :*: r) =                 RecordLit (Dhall.Map.union mapL mapR)@@ -2150,7 +2163,7 @@                 mapL = unsafeExpectRecord "genericToDhallWith (:*:)" declaredL                 mapR = unsafeExpectRecord "genericToDhallWith (:*:)" declaredR -        pure (InputType {..})+        pure (Encoder {..})  instance (GenericToDhall (f :*: g), Selector s, ToDhall a) => GenericToDhall ((f :*: g) :*: M1 S s (K1 i a)) where     genericToDhallWith options@InterpretOptions{..} = do@@ -2159,9 +2172,9 @@          nameR <- fmap fieldModifier (getSelName nR) -        InputType embedL declaredL <- genericToDhallWith options+        Encoder embedL declaredL <- genericToDhallWith options -        let InputType embedR declaredR = injectWith options+        let Encoder embedR declaredR = injectWith options          let embed (l :*: M1 (K1 r)) =                 RecordLit (Dhall.Map.insert nameR (embedR r) mapL)@@ -2173,7 +2186,7 @@               where                 mapL = unsafeExpectRecord "genericToDhallWith (:*:)" declaredL -        return (InputType {..})+        return (Encoder {..})  instance (Selector s, ToDhall a, GenericToDhall (f :*: g)) => GenericToDhall (M1 S s (K1 i a) :*: (f :*: g)) where     genericToDhallWith options@InterpretOptions{..} = do@@ -2182,9 +2195,9 @@          nameL <- fmap fieldModifier (getSelName nL) -        let InputType embedL declaredL = injectWith options+        let Encoder embedL declaredL = injectWith options -        InputType embedR declaredR <- genericToDhallWith options+        Encoder embedR declaredR <- genericToDhallWith options          let embed (M1 (K1 l) :*: r) =                 RecordLit (Dhall.Map.insert nameL (embedL l) mapR)@@ -2196,7 +2209,7 @@               where                 mapR = unsafeExpectRecord "genericToDhallWith (:*:)" declaredR -        return (InputType {..})+        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     genericToDhallWith options@InterpretOptions{..} = do@@ -2209,8 +2222,8 @@         nameL <- fmap fieldModifier (getSelName nL)         nameR <- fmap fieldModifier (getSelName nR) -        let InputType embedL declaredL = injectWith options-        let InputType embedR declaredR = injectWith options+        let Encoder embedL declaredL = injectWith options+        let Encoder embedR declaredR = injectWith options          let embed (M1 (K1 l) :*: M1 (K1 r)) =                 RecordLit@@ -2224,16 +2237,16 @@                         [ (nameL, declaredL), (nameR, declaredR) ]                     ) -        return (InputType {..})+        return (Encoder {..})  instance GenericToDhall U1 where-    genericToDhallWith _ = pure (InputType {..})+    genericToDhallWith _ = pure (Encoder {..})       where         embed _ = RecordLit mempty          declared = Record mempty -{-| The 'RecordType' applicative functor allows you to build a 'Type' parser+{-| The 'RecordDecoder' applicative functor allows you to build a 'Decoder'     from a Dhall record.      For example, let's take the following Haskell data type:@@ -2257,12 +2270,12 @@ >     289 > } -    Our parser has type 'Type' @Project@, but we can't build that out of any-    smaller parsers, as 'Type's cannot be combined (they are only 'Functor's).-    However, we can use a 'RecordType' to build a 'Type' for @Project@:+    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 :: Type Project+project :: Decoder Project project =   record     ( Project <$> field "name" strictText@@ -2272,8 +2285,8 @@ :} -} -newtype RecordType a =-  RecordType+newtype RecordDecoder a =+  RecordDecoder     ( Data.Functor.Product.Product         ( Control.Applicative.Const             ( Dhall.Map.Map@@ -2290,10 +2303,10 @@   deriving (Functor, Applicative)  --- | Run a 'RecordType' parser to build a 'Type' parser.-record :: RecordType a -> Dhall.Type a-record ( RecordType ( Data.Functor.Product.Pair ( Control.Applicative.Const fields ) ( Data.Functor.Compose.Compose extractF ) ) ) =-  Type+-- | 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 extractF ) ) ) =+  Decoder     { extract =         extractF     , expected =@@ -2302,27 +2315,26 @@   -- | Parse a single field of a record.-field :: Text -> Type a -> RecordType a-field key valueType@(Type extract expected) =+field :: Text -> Decoder a -> RecordDecoder a+field key valueDecoder@(Decoder extract expected) =   let     extractBody expr@(RecordLit fields) = case Dhall.Map.lookup key fields of       Just v -> extract v       _ -> typeError expected expr     extractBody expr = typeError expected expr   in-    RecordType+    RecordDecoder       ( Data.Functor.Product.Pair           ( Control.Applicative.Const               ( Dhall.Map.singleton                   key-                  ( Dhall.expected valueType )+                  ( Dhall.expected valueDecoder )               )           )           ( Data.Functor.Compose.Compose extractBody )       ) -{-| The 'UnionType' monoid allows you to build a 'Type' parser-    from a Dhall union+{-| The 'UnionDecoder' monoid allows you to build a 'Decoder' from a Dhall union      For example, let's take the following Haskell data type: @@ -2340,12 +2352,12 @@ > | Errored : Text > >.Result "Finish successfully" -    Our parser has type 'Type' @Status@, but we can't build that out of any-    smaller parsers, as 'Type's cannot be combined (they are only 'Functor's).-    However, we can use a 'UnionType' to build a 'Type' for @Status@:+    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 :: Type Status+status :: Decoder Status status = union   (  ( Queued  <$> constructor "Queued"  natural )   <> ( Result  <$> constructor "Result"  strictText )@@ -2354,21 +2366,21 @@ :}  -}-newtype UnionType a =-    UnionType-      ( Data.Functor.Compose.Compose (Dhall.Map.Map Text) Type a )+newtype UnionDecoder a =+    UnionDecoder+      ( Data.Functor.Compose.Compose (Dhall.Map.Map Text) Decoder a )   deriving (Functor) -instance Data.Semigroup.Semigroup (UnionType a) where-    (<>) = coerce ((<>) :: Dhall.Map.Map Text (Type a) -> Dhall.Map.Map Text (Type a) -> Dhall.Map.Map Text (Type a))+instance Data.Semigroup.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 (UnionType a) where-    mempty = coerce (mempty :: Dhall.Map.Map Text (Type a))+instance Monoid (UnionDecoder a) where+    mempty = coerce (mempty :: Dhall.Map.Map Text (Decoder a))     mappend = (Data.Semigroup.<>) --- | Run a 'UnionType' parser to build a 'Type' parser.-union :: UnionType a -> Type a-union (UnionType (Data.Functor.Compose.Compose mp)) = Type+-- | Run a 'UnionDecoder' to build a 'Decoder'.+union :: UnionDecoder a -> Decoder a+union (UnionDecoder (Data.Functor.Compose.Compose mp)) = Decoder     { extract  = extractF     , expected = Union expect     }@@ -2387,12 +2399,12 @@       in Data.Maybe.maybe (typeError (Union expect) e0) (uncurry extract) result  -- | Parse a single constructor of a union-constructor :: Text -> Type a -> UnionType a-constructor key valueType = UnionType-    ( Data.Functor.Compose.Compose (Dhall.Map.singleton key valueType) )+constructor :: Text -> Decoder a -> UnionDecoder a+constructor key valueDecoder = UnionDecoder+    ( Data.Functor.Compose.Compose (Dhall.Map.singleton key valueDecoder) ) -{-| The 'RecordInputType' divisible (contravariant) functor allows you to build-    an 'InputType' injector for a Dhall record.+{-| 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: @@ -2415,17 +2427,17 @@ >     289 > } -    Our injector has type 'InputType' @Project@, but we can't build that out of any-    smaller injectors, as 'InputType's cannot be combined (they are only 'Contravariant's).-    However, we can use an 'InputRecordType' to build an 'InputType' for @Project@:+    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 :: InputType Project+injectProject :: Encoder Project injectProject =-  inputRecord-    ( adapt >$< inputFieldWith "name" inject-            >*< inputFieldWith "description" inject-            >*< inputFieldWith "stars" inject+  recordEncoder+    ( adapt >$< encodeFieldWith "name" inject+            >*< encodeFieldWith "description" inject+            >*< encodeFieldWith "stars" inject     )   where     adapt (Project{..}) = (projectName, (projectDescription, projectStars))@@ -2434,12 +2446,12 @@     Or, since we are simply using the `ToDhall` instance to inject each field, we could write  >>> :{-injectProject :: InputType Project+injectProject :: Encoder Project injectProject =-  inputRecord-    ( adapt >$< inputField "name"-            >*< inputField "description"-            >*< inputField "stars"+  recordEncoder+    ( adapt >$< encodeField "name"+            >*< encodeField "description"+            >*< encodeField "stars"     )   where     adapt (Project{..}) = (projectName, (projectDescription, projectStars))@@ -2454,41 +2466,40 @@ infixr 5 >*<  -- | Intermediate type used for building a `ToDhall` instance for a record-newtype RecordInputType a-  = RecordInputType (Dhall.Map.Map Text (InputType a))+newtype RecordEncoder a+  = RecordEncoder (Dhall.Map.Map Text (Encoder a)) -instance Contravariant RecordInputType where-  contramap f (RecordInputType inputTypeRecord) = RecordInputType $ contramap f <$> inputTypeRecord+instance Contravariant RecordEncoder where+  contramap f (RecordEncoder encodeTypeRecord) = RecordEncoder $ contramap f <$> encodeTypeRecord -instance Divisible RecordInputType where-  divide f (RecordInputType bInputTypeRecord) (RecordInputType cInputTypeRecord) =-      RecordInputType+instance Divisible RecordEncoder where+  divide f (RecordEncoder bEncoderRecord) (RecordEncoder cEncoderRecord) =+      RecordEncoder     $ Dhall.Map.union-      ((contramap $ fst . f) <$> bInputTypeRecord)-      ((contramap $ snd . f) <$> cInputTypeRecord)-  conquer = RecordInputType mempty+      ((contramap $ fst . f) <$> bEncoderRecord)+      ((contramap $ snd . f) <$> cEncoderRecord)+  conquer = RecordEncoder mempty  {-| Specify how to encode one field of a record by supplying an explicit-    `InputType` for that field+    `Encoder` for that field -}-inputFieldWith :: Text -> InputType a -> RecordInputType a-inputFieldWith name inputType = RecordInputType $ Dhall.Map.singleton name inputType+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 -}-inputField :: ToDhall a => Text -> RecordInputType a-inputField name = inputFieldWith name inject+encodeField :: ToDhall a => Text -> RecordEncoder a+encodeField name = encodeFieldWith name inject --- | Convert a `RecordInputType` into the equivalent `InputType`-inputRecord :: RecordInputType a -> InputType a-inputRecord (RecordInputType inputTypeRecord) = InputType makeRecordLit recordType+-- | Convert a `RecordEncoder` into the equivalent `Encoder`+recordEncoder :: RecordEncoder a -> Encoder a+recordEncoder (RecordEncoder encodeTypeRecord) = Encoder makeRecordLit recordType   where-    recordType = Record $ declared <$> inputTypeRecord-    makeRecordLit x = RecordLit $ (($ x) . embed) <$> inputTypeRecord+    recordType = Record $ declared <$> encodeTypeRecord+    makeRecordLit x = RecordLit $ (($ x) . embed) <$> encodeTypeRecord -{-| 'UnionInputType' allows you to build an 'InputType' injector for a Dhall-    record.+{-| 'UnionEncoder' allows you to build an 'Encoder' for a Dhall record.      For example, let's take the following Haskell data type: @@ -2506,16 +2517,16 @@ > | Errored : Text > >.Result "Finish successfully" -    Our injector has type 'InputType' @Status@, but we can't build that out of any-    smaller injectors, as 'InputType's cannot be combined.-    However, we can use an 'UnionInputType' to build an 'InputType' for @Status@:+    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 :: InputType Status-injectStatus = adapt >$< inputUnion-  (   inputConstructorWith "Queued"  inject-  >|< inputConstructorWith "Result"  inject-  >|< inputConstructorWith "Errored" inject+injectStatus :: Encoder Status+injectStatus = adapt >$< unionEncoder+  (   encodeConstructorWith "Queued"  inject+  >|< encodeConstructorWith "Result"  inject+  >|< encodeConstructorWith "Errored" inject   )   where     adapt (Queued  n) = Left n@@ -2526,11 +2537,11 @@     Or, since we are simply using the `ToDhall` instance to inject each branch, we could write  >>> :{-injectStatus :: InputType Status-injectStatus = adapt >$< inputUnion-  (   inputConstructor "Queued"-  >|< inputConstructor "Result"-  >|< inputConstructor "Errored"+injectStatus :: Encoder Status+injectStatus = adapt >$< unionEncoder+  (   encodeConstructor "Queued"+  >|< encodeConstructor "Result"+  >|< encodeConstructor "Errored"   )   where     adapt (Queued  n) = Left n@@ -2539,8 +2550,8 @@ :}  -}-newtype UnionInputType a =-  UnionInputType+newtype UnionEncoder a =+  UnionEncoder     ( Data.Functor.Product.Product         ( Control.Applicative.Const             ( Dhall.Map.Map@@ -2553,16 +2564,16 @@     )   deriving (Contravariant) --- | Combines two 'UnionInputType' values.  See 'UnionInputType' for usage+-- | Combines two 'UnionEncoder' values.  See 'UnionEncoder' for usage -- notes. -- -- Ideally, this matches 'Data.Functor.Contravariant.Divisible.chosen';--- however, this allows 'UnionInputType' to not need a 'Divisible' instance+-- however, this allows 'UnionEncoder' to not need a 'Divisible' instance -- itself (since no instance is possible).-(>|<) :: UnionInputType a -> UnionInputType b -> UnionInputType (Either a b)-UnionInputType (Data.Functor.Product.Pair (Control.Applicative.Const mx) (Op fx))-    >|< UnionInputType (Data.Functor.Product.Pair (Control.Applicative.Const my) (Op fy)) =-    UnionInputType+(>|<) :: 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) )@@ -2570,10 +2581,10 @@  infixr 5 >|< --- | Convert a `UnionInputType` into the equivalent `InputType`-inputUnion :: UnionInputType a -> InputType a-inputUnion ( UnionInputType ( Data.Functor.Product.Pair ( Control.Applicative.Const fields ) ( Op embedF ) ) ) =-    InputType+-- | 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@@ -2585,29 +2596,29 @@   where     fields' = fmap notEmptyRecord fields -{-| Specify how to encode an alternative by providing an explicit `InputType`+{-| Specify how to encode an alternative by providing an explicit `Encoder`     for that alternative -}-inputConstructorWith+encodeConstructorWith     :: Text-    -> InputType a-    -> UnionInputType a-inputConstructorWith name inputType = UnionInputType $+    -> Encoder a+    -> UnionEncoder a+encodeConstructorWith name encodeType = UnionEncoder $     Data.Functor.Product.Pair       ( Control.Applicative.Const           ( Dhall.Map.singleton               name-              ( declared inputType )+              ( declared encodeType )           )       )-      ( Op ( (name,) . embed inputType )+      ( Op ( (name,) . embed encodeType )       )  {-| Specify how to encode an alternative by using the default `ToDhall` instance     for that type -}-inputConstructor+encodeConstructor     :: ToDhall a     => Text-    -> UnionInputType a-inputConstructor name = inputConstructorWith name inject+    -> UnionEncoder a+encodeConstructor name = encodeConstructorWith name inject
src/Dhall/Binary.hs view
@@ -1,967 +1,1248 @@-{-# LANGUAGE FlexibleContexts   #-}-{-# LANGUAGE FlexibleInstances  #-}-{-# LANGUAGE RecordWildCards    #-}-{-# LANGUAGE OverloadedStrings  #-}--{-| This module contains logic for converting Dhall expressions to and from-    CBOR expressions which can in turn be converted to and from a binary-    representation--}--module Dhall.Binary-    ( -- * Standard versions-      StandardVersion(..)-    , renderStandardVersion--    -- * Encoding and decoding-    , ToTerm(..)-    , FromTerm(..)-    , encodeExpression-    , decodeExpression--    -- * Exceptions-    , DecodingFailure(..)-    ) where--import Codec.CBOR.Term (Term(..))-import Control.Applicative (empty, (<|>))-import Control.Exception (Exception)-import Dhall.Core-    ( Binding(..)-    , Chunks(..)-    , Const(..)-    , Directory(..)-    , DhallDouble(..)-    , Expr(..)-    , File(..)-    , FilePrefix(..)-    , Import(..)-    , ImportHashed(..)-    , ImportMode(..)-    , ImportType(..)-    , MultiLet(..)-    , Scheme(..)-    , URL(..)-    , Var(..)-    )--import Data.Foldable (toList)-import Data.Monoid ((<>))-import Data.Text (Text)-import Data.Void (Void, absurd)-import GHC.Float (double2Float, float2Double)--import qualified Control.Monad       as Monad-import qualified Data.ByteArray-import qualified Data.ByteString-import qualified Data.Sequence-import qualified Dhall.Core-import qualified Dhall.Crypto-import qualified Dhall.Map-import qualified Dhall.Set--{-| 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 `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--}-unApply :: Expr s a -> (Expr s a, [Expr s a])-unApply e₀ = (baseFunction₀, diffArguments₀ [])-  where-    ~(baseFunction₀, diffArguments₀) = go e₀--    go (App f a) = (baseFunction, diffArguments . (a :))-      where-        ~(baseFunction, diffArguments) = go f--    go (Note _ e) = go e--    go baseFunction = (baseFunction, id)---- | Types that can be encoded as a CBOR `Term`-class ToTerm a where-    encode :: a -> Term--instance ToTerm a => ToTerm (Expr Void a) where-    encode (Var (V "_" n)) =-        TInt n-    encode (Var (V x n)) =-        TList [ TString x, TInt n ]-    encode NaturalBuild =-        TString "Natural/build"-    encode NaturalFold =-        TString "Natural/fold"-    encode NaturalIsZero =-        TString "Natural/isZero"-    encode NaturalEven =-        TString "Natural/even"-    encode NaturalOdd =-        TString "Natural/odd"-    encode NaturalToInteger =-        TString "Natural/toInteger"-    encode NaturalShow =-        TString "Natural/show"-    encode NaturalSubtract =-        TString "Natural/subtract"-    encode IntegerToDouble =-        TString "Integer/toDouble"-    encode IntegerShow =-        TString "Integer/show"-    encode DoubleShow =-        TString "Double/show"-    encode ListBuild =-        TString "List/build"-    encode ListFold =-        TString "List/fold"-    encode ListLength =-        TString "List/length"-    encode ListHead =-        TString "List/head"-    encode ListLast =-        TString "List/last"-    encode ListIndexed =-        TString "List/indexed"-    encode ListReverse =-        TString "List/reverse"-    encode OptionalFold =-        TString "Optional/fold"-    encode OptionalBuild =-        TString "Optional/build"-    encode Bool =-        TString "Bool"-    encode Optional =-        TString "Optional"-    encode None =-        TString "None"-    encode Natural =-        TString "Natural"-    encode Integer =-        TString "Integer"-    encode Double =-        TString "Double"-    encode Text =-        TString "Text"-    encode TextShow =-        TString "Text/show"-    encode List =-        TString "List"-    encode (Const Type) =-        TString "Type"-    encode (Const Kind) =-        TString "Kind"-    encode (Const Sort) =-        TString "Sort"-    encode e@(App _ _) =-        TList ([ TInt 0, f₁ ] ++ map encode arguments)-      where-        (f₀, arguments) = unApply e--        f₁ = encode f₀-    encode (Lam "_" _A₀ b₀) =-        TList [ TInt 1, _A₁, b₁ ]-      where-        _A₁ = encode _A₀-        b₁  = encode b₀-    encode (Lam x _A₀ b₀) =-        TList [ TInt 1, TString x, _A₁, b₁ ]-      where-        _A₁ = encode _A₀-        b₁  = encode b₀-    encode (Pi "_" _A₀ _B₀) =-        TList [ TInt 2, _A₁, _B₁ ]-      where-        _A₁ = encode _A₀-        _B₁ = encode _B₀-    encode (Pi x _A₀ _B₀) =-        TList [ TInt 2, TString x, _A₁, _B₁ ]-      where-        _A₁ = encode _A₀-        _B₁ = encode _B₀-    encode (BoolOr l₀ r₀) =-        TList [ TInt 3, TInt 0, l₁, r₁ ]-      where-        l₁ = encode l₀-        r₁ = encode r₀-    encode (BoolAnd l₀ r₀) =-        TList [ TInt 3, TInt 1, l₁, r₁ ]-      where-        l₁ = encode l₀-        r₁ = encode r₀-    encode (BoolEQ l₀ r₀) =-        TList [ TInt 3, TInt 2, l₁, r₁ ]-      where-        l₁ = encode l₀-        r₁ = encode r₀-    encode (BoolNE l₀ r₀) =-        TList [ TInt 3, TInt 3, l₁, r₁ ]-      where-        l₁ = encode l₀-        r₁ = encode r₀-    encode (NaturalPlus l₀ r₀) =-        TList [ TInt 3, TInt 4, l₁, r₁ ]-      where-        l₁ = encode l₀-        r₁ = encode r₀-    encode (NaturalTimes l₀ r₀) =-        TList [ TInt 3, TInt 5, l₁, r₁ ]-      where-        l₁ = encode l₀-        r₁ = encode r₀-    encode (TextAppend l₀ r₀) =-        TList [ TInt 3, TInt 6, l₁, r₁ ]-      where-        l₁ = encode l₀-        r₁ = encode r₀-    encode (ListAppend l₀ r₀) =-        TList [ TInt 3, TInt 7, l₁, r₁ ]-      where-        l₁ = encode l₀-        r₁ = encode r₀-    encode (Combine l₀ r₀) =-        TList [ TInt 3, TInt 8, l₁, r₁ ]-      where-        l₁ = encode l₀-        r₁ = encode r₀-    encode (Prefer l₀ r₀) =-        TList [ TInt 3, TInt 9, l₁, r₁ ]-      where-        l₁ = encode l₀-        r₁ = encode r₀-    encode (CombineTypes l₀ r₀) =-        TList [ TInt 3, TInt 10, l₁, r₁ ]-      where-        l₁ = encode l₀-        r₁ = encode r₀-    encode (ImportAlt l₀ r₀) =-        TList [ TInt 3, TInt 11, l₁, r₁ ]-      where-        l₁ = encode l₀-        r₁ = encode r₀-    encode (Equivalent l₀ r₀) =-        TList [ TInt 3, TInt 12, l₁, r₁ ]-      where-        l₁ = encode l₀-        r₁ = encode r₀-    encode (RecordCompletion l₀ r₀) =-        TList [ TInt 3, TInt 13, l₁, r₁ ]-      where-        l₁ = encode l₀-        r₁ = encode r₀-    encode (ListLit _T₀ xs₀)-        | null xs₀  = TList [ TInt label, _T₁ ]-        | otherwise = TList ([ TInt 4, TNull ] ++ xs₁)-      where-        (label, _T₁) = case _T₀ of-            Nothing           -> (4 , TNull)-            Just (App List t) -> (4 , encode t)-            Just t            -> (28, encode t)--        xs₁ = map encode (Data.Foldable.toList xs₀)-    encode (Some t₀) =-        TList [ TInt 5, TNull, t₁ ]-      where-        t₁ = encode t₀-    encode (Merge t₀ u₀ Nothing) =-        TList [ TInt 6, t₁, u₁ ]-      where-        t₁ = encode t₀-        u₁ = encode u₀-    encode (Merge t₀ u₀ (Just _T₀)) =-        TList [ TInt 6, t₁, u₁, _T₁ ]-      where-        t₁  = encode t₀-        u₁  = encode u₀-        _T₁ = encode _T₀-    encode (Record xTs₀) =-        TList [ TInt 7, TMap xTs₁ ]-      where-        xTs₁ = do-            (x₀, _T₀) <- Dhall.Map.toList (Dhall.Map.sort xTs₀)-            let x₁  = TString x₀-            let _T₁ = encode _T₀-            return (x₁, _T₁)-    encode (RecordLit xts₀) =-        TList [ TInt 8, TMap xts₁ ]-      where-        xts₁ = do-            (x₀, t₀) <- Dhall.Map.toList (Dhall.Map.sort xts₀)-            let x₁ = TString x₀-            let t₁ = encode t₀-            return (x₁, t₁)-    encode (Field t₀ x) =-        TList [ TInt 9, t₁, TString x ]-      where-        t₁ = encode t₀-    encode (Project t₀ (Left xs₀)) =-        TList ([ TInt 10, t₁ ] ++ xs₁)-      where-        t₁  = encode t₀-        xs₁ = map TString (Dhall.Set.toList xs₀)-    encode (Project t₀ (Right _T₀)) =-        TList [ TInt 10, t₁, TList [ _T₁ ] ]-      where-        _T₁ = encode _T₀-        t₁  = encode t₀-    encode (Union xTs₀) =-        TList [ TInt 11, TMap xTs₁ ]-      where-        xTs₁ = do-            (x₀, mT₀) <- Dhall.Map.toList (Dhall.Map.sort xTs₀)--            let x₁  = TString x₀--            let _T₁ = case mT₀ of-                    Nothing  -> TNull-                    Just _T₀ -> encode _T₀--            return (x₁, _T₁)-    encode (BoolLit b) =-        TBool b-    encode (BoolIf t₀ l₀ r₀) =-        TList [ TInt 14, t₁, l₁, r₁ ]-      where-        t₁ = encode t₀-        l₁ = encode l₀-        r₁ = encode r₀-    encode (NaturalLit n) =-        TList [ TInt 15, TInteger (fromIntegral n) ]-    encode (IntegerLit n) =-        TList [ TInt 16, TInteger n ]-    encode (DoubleLit d) =-        encode d-    encode (TextLit (Chunks xys₀ z₀)) =-        TList ([ TInt 18 ] ++ xys₁ ++ [ z₁ ])-      where-        xys₁ = do-            (x₀, y₀) <- xys₀-            let x₁ = TString x₀-            let y₁ = encode y₀-            [ x₁, y₁ ]--        z₁ = TString z₀-    encode (Assert t₀) =-        TList [ TInt 19, t₁ ]-      where-        t₁ = encode t₀-    encode (Embed x) =-        encode x-    encode (Let a b) =-        TList ([ TInt 25 ] ++ as₁ ++ [ b₁ ])-      where-        MultiLet as₀ b₀ = Dhall.Core.multiLet a b--        as₁ = do-            Binding _ x₀ _ mA₀ _ a₀ <- toList as₀--            let mA₁ = case mA₀ of-                    Nothing       -> TNull-                    Just (_, _A₀) -> encode _A₀--            let a₁ = encode a₀--            [ TString x₀, mA₁, a₁ ]--        b₁ = encode b₀-    encode (Annot t₀ _T₀) =-        TList [ TInt 26, t₁, _T₁ ]-      where-        t₁  = encode t₀-        _T₁ = encode _T₀-    encode (ToMap t₀ Nothing) =-        TList [ TInt 27, t₁ ]-      where-        t₁ = encode t₀-    encode (ToMap t₀ (Just _T₀)) =-        TList [ TInt 27, t₁, _T₁ ]-      where-        t₁  = encode t₀-        _T₁ = encode _T₀-    encode (Note a _) = absurd a--instance ToTerm Import where-    encode import_ =-        case importType of-            Remote (URL { scheme = scheme₀, ..}) ->-                TList-                    (   prefix-                    ++  [ TInt scheme₁, using, TString authority ]-                    ++  map TString (reverse components)-                    ++  [ TString file ]-                    ++  (case query    of Nothing -> [ TNull ]; Just q -> [ TString q ])-                    )-              where-                using = case headers of-                    Nothing ->-                        TNull-                    Just h ->-                        encodeExpression h--                scheme₁ = case scheme₀ of-                    HTTP  -> 0-                    HTTPS -> 1-                File {..} = path--                Directory {..} = directory--            Local prefix₀ path ->-                    TList-                        (   prefix-                        ++  [ TInt prefix₁ ]-                        ++  map TString components₁-                        ++  [ TString file ]-                        )-              where-                File {..} = path--                Directory {..} = directory--                prefix₁ = case prefix₀ of-                  Absolute -> 2-                  Here     -> 3-                  Parent   -> 4-                  Home     -> 5--                components₁ = reverse components--            Env x ->-                TList (prefix ++ [ TInt 6, TString x ])--            Missing ->-                TList (prefix ++ [ TInt 7 ])-      where-        prefix = [ TInt 24, h, m ]-          where-            h = case hash of-                Nothing ->-                    TNull-                Just digest ->-                    TBytes ("\x12\x20" <> Data.ByteArray.convert digest)--            m = TInt (case importMode of Code -> 0; RawText -> 1; Location -> 2;)--        Import {..} = import_--        ImportHashed {..} = importHashed--instance ToTerm Void where-    encode = absurd--instance ToTerm DhallDouble where-    encode (DhallDouble n64)-        -- cborg always encodes NaN as a half-precision float of value "7e00"-        | useHalf   = THalf n32-        | useFloat  = TFloat n32-        | otherwise = TDouble n64-      where-        n32      = double2Float n64-        useFloat = n64 == float2Double n32-        -- the other four cases for Half-floats are -0.0, 0.0 and the infinities-        useHalf  = n64 == 0.0 || n64 == infinity || n64 == -infinity-        infinity = 1/0 :: Double---- | Types that can be decoded from a CBOR `Term`-class FromTerm a where-    decode :: Term -> Maybe a--instance FromTerm a => FromTerm (Expr s a) where-    decode (TInt n) =-        return (Var (V "_" n))-    decode (TInteger n) =-        return (Var (V "_" (fromIntegral n)))-    decode (TString "Natural/build") =-        return NaturalBuild-    decode (TString "Natural/fold") =-        return NaturalFold-    decode (TString "Natural/isZero") =-        return NaturalIsZero-    decode (TString "Natural/even") =-        return NaturalEven-    decode (TString "Natural/odd") =-        return NaturalOdd-    decode (TString "Natural/toInteger") =-        return NaturalToInteger-    decode (TString "Natural/show") =-        return NaturalShow-    decode (TString "Natural/subtract") =-        return NaturalSubtract-    decode (TString "Integer/toDouble") =-        return IntegerToDouble-    decode (TString "Integer/show") =-        return IntegerShow-    decode (TString "Double/show") =-        return DoubleShow-    decode (TString "List/build") =-        return ListBuild-    decode (TString "List/fold") =-        return ListFold-    decode (TString "List/length") =-        return ListLength-    decode (TString "List/head") =-        return ListHead-    decode (TString "List/last") =-        return ListLast-    decode (TString "List/indexed") =-        return ListIndexed-    decode (TString "List/reverse") =-        return ListReverse-    decode (TString "Optional/fold") =-        return OptionalFold-    decode (TString "Optional/build") =-        return OptionalBuild-    decode (TString "Bool") =-        return Bool-    decode (TString "Optional") =-        return Optional-    decode (TString "None") =-        return None-    decode (TString "Natural") =-        return Natural-    decode (TString "Integer") =-        return Integer-    decode (TString "Double") =-        return Double-    decode (TString "Text") =-        return Text-    decode (TString "Text/show") =-        return TextShow-    decode (TString "List") =-        return List-    decode (TString "Type") =-        return (Const Type)-    decode (TString "Kind") =-        return (Const Kind)-    decode (TString "Sort") =-        return (Const Sort)-    decode (TString "_") =-        empty-    decode (TList [ TString x, TInt n ]) = do-        Monad.guard (x /= "_")-        return (Var (V x n))-    decode (TList [ TString x, TInteger n ]) = do-        Monad.guard (x /= "_")-        return (Var (V x (fromIntegral n)))-    decode (TList (TInt 0 : f₁ : xs₁)) = do-        f₀  <- decode f₁-        xs₀ <- traverse decode xs₁-        Monad.guard (not (null xs₀))-        return (foldl App f₀ xs₀)-    decode (TList [ TInt 1, _A₁, b₁ ]) = do-        _A₀ <- decode _A₁-        b₀  <- decode b₁-        return (Lam "_" _A₀ b₀)-    decode (TList [ TInt 1, TString x, _A₁, b₁ ]) = do-        Monad.guard (x /= "_")-        _A₀ <- decode _A₁-        b₀  <- decode b₁-        return (Lam x _A₀ b₀)-    decode (TList [ TInt 2, _A₁, _B₁ ]) = do-        _A₀ <- decode _A₁-        _B₀ <- decode _B₁-        return (Pi "_" _A₀ _B₀)-    decode (TList [ TInt 2, TString x, _A₁, _B₁ ]) = do-        Monad.guard (x /= "_")-        _A₀ <- decode _A₁-        _B₀ <- decode _B₁-        return (Pi x _A₀ _B₀)-    decode (TList [ TInt 3, TInt n, l₁, r₁ ]) = do-        l₀ <- decode l₁-        r₀ <- decode r₁-        op <- case n of-                0  -> return BoolOr-                1  -> return BoolAnd-                2  -> return BoolEQ-                3  -> return BoolNE-                4  -> return NaturalPlus-                5  -> return NaturalTimes-                6  -> return TextAppend-                7  -> return ListAppend-                8  -> return Combine-                9  -> return Prefer-                10 -> return CombineTypes-                11 -> return ImportAlt-                12 -> return Equivalent-                13 -> return RecordCompletion-                _  -> empty-        return (op l₀ r₀)-    decode (TList [ TInt 4, _T₁ ]) = do-        _T₀ <- decode _T₁-        return (ListLit (Just (App List _T₀)) empty)-    decode (TList (TInt 4 : TNull : xs₁ )) = do-        xs₀ <- traverse decode xs₁-        return (ListLit Nothing (Data.Sequence.fromList xs₀))-    decode (TList [ TInt 5, TNull, t₁ ]) = do-        t₀ <- decode t₁-        return (Some t₀)-    decode (TList [ TInt 6, t₁, u₁ ]) = do-        t₀ <- decode t₁-        u₀ <- decode u₁-        return (Merge t₀ u₀ Nothing)-    decode (TList [ TInt 6, t₁, u₁, _T₁ ]) = do-        t₀  <- decode t₁-        u₀  <- decode u₁-        _T₀ <- decode _T₁-        return (Merge t₀ u₀ (Just _T₀))-    decode (TList [ TInt 7, TMap xTs₁ ]) = do-        let process (TString x, _T₁) = do-                _T₀ <- decode _T₁--                return (x, _T₀)-            process _ =-                empty--        xTs₀ <- traverse process xTs₁--        return (Record (Dhall.Map.fromList xTs₀))-    decode (TList [ TInt 8, TMap xts₁ ]) = do-        let process (TString x, t₁) = do-               t₀ <- decode t₁--               return (x, t₀)-            process _ =-                empty--        xts₀ <- traverse process xts₁--        return (RecordLit (Dhall.Map.fromList xts₀))-    decode (TList [ TInt 9, t₁, TString x ]) = do-        t₀ <- decode t₁--        return (Field t₀ x)-    decode (TList (TInt 10 : t₁ : xs₁)) = do-        t₀ <- decode t₁--        let expectString (TString x) = return x-            expectString  _          = empty--        let decodeLeft = do-                strings <- traverse expectString xs₁--                return (Left (Dhall.Set.fromList strings))--        let decodeRight =-                case xs₁ of-                    [ TList [ _T₁ ] ] -> do-                        _T₀ <- decode _T₁--                        return (Right _T₀)-                    _ -> do-                        empty--        xs₀ <- decodeLeft <|> decodeRight--        return (Project t₀ xs₀)-    decode (TList [ TInt 11, TMap xTs₁ ]) = do-        let process (TString x, _T₁) = do-                mT₀ <- case _T₁ of-                    TNull -> return Nothing-                    _     -> fmap Just (decode _T₁)--                return (x, mT₀)-            process _ =-                empty--        xTs₀ <- traverse process xTs₁--        return (Union (Dhall.Map.fromList xTs₀))-    decode (TBool b) = do-        return (BoolLit b)-    decode (TList [ TInt 14, t₁, l₁, r₁ ]) = do-        t₀ <- decode t₁-        l₀ <- decode l₁-        r₀ <- decode r₁--        return (BoolIf t₀ l₀ r₀)-    decode (TList [ TInt 15, TInt n ]) = do-        Monad.guard (0 <= n)-        return (NaturalLit (fromIntegral n))-    decode (TList [ TInt 15, TInteger n ]) = do-        return (NaturalLit (fromInteger n))-    decode (TList [ TInt 16, TInt n ]) = do-        return (IntegerLit (fromIntegral n))-    decode (TList [ TInt 16, TInteger n ]) = do-        return (IntegerLit n)-    decode (THalf n) = do-        return (DoubleLit (DhallDouble (float2Double n)))-    decode (TFloat n) = do-        return (DoubleLit (DhallDouble (float2Double n)))-    decode (TDouble n) = do-        return (DoubleLit (DhallDouble n))-    decode (TList (TInt 18 : xs)) = do-        let process (TString x : y₁ : zs) = do-                y₀ <- decode y₁--                ~(xys, z) <- process zs--                return ((x, y₀) : xys, z)-            process [ TString z ] = do-                return ([], z)-            process _ = do-                empty--        (xys, z) <- process xs--        return (TextLit (Chunks xys z))-    decode (TList [ TInt 19, t₁ ]) = do-        t₀ <- decode t₁--        return (Assert t₀)-    decode e@(TList (TInt 24 : _)) = fmap Embed (decode e)-    decode (TList (TInt 25 : xs)) = do-        let process (TString x : _A₁ : a₁ : ls₁) = do-                mA₀ <- case _A₁ of-                    TNull -> return Nothing-                    _     -> do-                        _A₀ <- decode _A₁-                        return (Just (Nothing, _A₀))--                a₀  <- decode a₁--                b₀ <- case ls₁ of-                    [ b₁ ] -> decode b₁-                    _      -> process ls₁--                return (Let (Binding Nothing x Nothing mA₀ Nothing a₀) b₀)-            process _ = do-                empty--        process xs-    decode (TList [ TInt 26, t₁, _T₁ ]) = do-        t₀  <- decode t₁-        _T₀ <- decode _T₁-        return (Annot t₀ _T₀)-    decode (TList [ TInt 27, t₁ ]) = do-        t₀ <- decode t₁-        return (ToMap t₀ Nothing)-    decode (TList [ TInt 27, t₁, _T₁ ]) = do-        t₀ <- decode t₁-        _T₀ <- decode _T₁-        return (ToMap t₀ (Just _T₀))-    decode (TList [ TInt 28, _T₁ ]) = do-        _T₀ <- decode _T₁-        return (ListLit (Just _T₀) empty)-    decode _ =-        empty--instance FromTerm Import where-    decode (TList (TInt 24 : h : TInt mode : TInt n : xs)) = do-        hash <- case h of-            TNull -> do-                return Nothing--            TBytes bytes -> do-                let (prefix, suffix) = Data.ByteString.splitAt 2 bytes--                case prefix of-                    "\x12\x20" -> return ()-                    _          -> empty--                digest <- case Dhall.Crypto.sha256DigestFromByteString suffix of-                    Nothing     -> empty-                    Just digest -> return digest--                return (Just digest)--            _ -> do-                empty--        importMode <- case mode of-            0 -> return Code-            1 -> return RawText-            2 -> return Location-            _ -> empty--        let remote scheme = do-                let process [ TString file, q ] = do-                        query <- case q of-                            TNull     -> return Nothing-                            TString x -> return (Just x)-                            _         -> empty-                        return ([], file, query)-                    process (TString path : ys) = do-                        (paths, file, query) <- process ys-                        return (path : paths, file, query)-                    process _ = do-                        empty--                (headers, authority, paths, file, query) <- case xs of-                    headers₀ : TString authority : ys -> do-                        headers₁ <- case headers₀ of-                            TNull -> do-                                return Nothing-                            _     -> do-                                headers <- decode headers₀--                                return (Just headers)-                        (paths, file, query) <- process ys-                        return (headers₁, authority, paths, file, query)-                    _ -> do-                        empty--                let components = reverse paths-                let directory  = Directory {..}-                let path       = File {..}--                return (Remote (URL {..}))--        let local prefix = do-                let process [ TString file ] = do-                        return ([], file)-                    process (TString path : ys) = do-                        (paths, file) <- process ys-                        return (path : paths, file)-                    process _ =-                        empty--                (paths, file) <- process xs--                let components = reverse paths-                let directory  = Directory {..}--                return (Local prefix (File {..}))--        let env = do-                case xs of-                    [ TString x ] -> return (Env x)-                    _             -> empty--        let missing = return Missing--        importType <- case n of-            0 -> remote HTTP-            1 -> remote HTTPS-            2 -> local Absolute-            3 -> local Here-            4 -> local Parent-            5 -> local Home-            6 -> env-            7 -> missing-            _ -> empty--        let importHashed = ImportHashed {..}--        return (Import {..})--    decode _ = empty--instance FromTerm Void where-    decode _ = empty--strip55799Tag :: Term -> Term-strip55799Tag term =-    case term of-        TInt a ->-            TInt a-        TInteger a ->-            TInteger a-        TBytes a ->-            TBytes a-        TBytesI a ->-            TBytesI a-        TString a ->-            TString a-        TStringI a ->-            TStringI a-        TList as ->-            TList (fmap strip55799Tag as)-        TListI as ->-            TListI (fmap strip55799Tag as)-        TMap as ->-            TMap (fmap adapt as)-          where-            adapt (a, b) = (strip55799Tag a, strip55799Tag b)-        TMapI as ->-            TMapI (fmap adapt as)-          where-            adapt (a, b) = (strip55799Tag a, strip55799Tag b)-        TTagged 55799 b ->-            strip55799Tag b-        TTagged a b->-            TTagged a (strip55799Tag b)-        TBool a ->-            TBool a-        TNull ->-            TNull-        TSimple a ->-            TSimple a-        THalf a ->-            THalf a-        TFloat a ->-            TFloat a-        TDouble a ->-            TDouble a---- | Encode a Dhall expression as a CBOR `Term`------ This 'Dhall.Core.denote's the expression before encoding it. To encode an--- already denoted expression, it is more efficient to directly use 'encode'.-encodeExpression :: Expr s Import -> Term-encodeExpression e = encode (Dhall.Core.denote e :: Expr Void Import)---- | Decode a Dhall expression from a CBOR `Term`-decodeExpression :: FromTerm a => Term -> Either DecodingFailure (Expr s a)-decodeExpression term =-    case decodeWithoutVersion <|> decodeWithVersion of-        Just expression -> Right expression-        Nothing         -> Left (CBORIsNotDhall term)-  where-    strippedTerm = strip55799Tag term-    -- This is the behavior specified by the standard-    decodeWithoutVersion = decode strippedTerm--    -- For backwards compatibility with older expressions that have a version-    -- tag to ease the migration-    decodeWithVersion = do-        TList [ TString version, taggedTerm ] <- return strippedTerm--        -- "_" has never been a valid version string, and this ensures that we-        -- don't interpret `[ "_", 0 ]` as the expression `_` (encoded as `0`)-        -- tagged with a version string of `"_"`-        Monad.guard (version /= "_")--        decode taggedTerm--{-| This indicates that a given CBOR expression did not correspond to a valid-    Dhall expression--}-data DecodingFailure = CBORIsNotDhall Term-    deriving (Eq)--instance Exception DecodingFailure--_ERROR :: String-_ERROR = "\ESC[1;31mError\ESC[0m"--instance Show DecodingFailure where-    show (CBORIsNotDhall term) =-            _ERROR <> ": Cannot decode CBOR to Dhall\n"-        <>  "\n"-        <>  "The following CBOR expression does not encode a valid Dhall expression\n"-        <>  "\n"-        <>  "↳ " <> show term <> "\n"+{-# LANGUAGE BangPatterns       #-}+{-# LANGUAGE FlexibleContexts   #-}+{-# LANGUAGE FlexibleInstances  #-}+{-# LANGUAGE RecordWildCards    #-}+{-# LANGUAGE OverloadedStrings  #-}++{-# OPTIONS_GHC -fno-warn-orphans #-}++{-| This module contains logic for converting Dhall expressions to and from+    CBOR expressions which can in turn be converted to and from a binary+    representation+-}++module Dhall.Binary+    ( -- * Standard versions+      StandardVersion(..)+    , renderStandardVersion++    -- * Encoding and decoding+    , encodeExpression+    , decodeExpression++    -- * Exceptions+    , DecodingFailure(..)+    ) where++import Codec.CBOR.Decoding (Decoder, TokenType(..))+import Codec.CBOR.Encoding (Encoding)+import Codec.Serialise (Serialise(encode, decode))+import Control.Applicative (empty, (<|>))+import Control.Exception (Exception)+import Data.ByteString.Lazy (ByteString)+import Dhall.Syntax+    ( Binding(..)+    , Chunks(..)+    , Const(..)+    , Directory(..)+    , DhallDouble(..)+    , Expr(..)+    , File(..)+    , FilePrefix(..)+    , Import(..)+    , ImportHashed(..)+    , ImportMode(..)+    , ImportType(..)+    , MultiLet(..)+    , Scheme(..)+    , URL(..)+    , Var(..)+    )++import Data.Foldable (toList, foldl')+import Data.Monoid ((<>))+import Data.Text (Text)+import Data.Void (Void, absurd)+import GHC.Float (double2Float, float2Double)++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 Control.Monad        as Monad+import qualified Data.ByteArray+import qualified Data.ByteString+import qualified Data.ByteString.Lazy+import qualified Data.Sequence+import qualified Data.Text            as Text+import qualified Dhall.Syntax+import qualified Dhall.Crypto+import qualified Dhall.Map+import qualified Dhall.Set+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 `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+-}+unApply :: Expr s a -> (Expr s a, [Expr s a])+unApply e₀ = (baseFunction₀, diffArguments₀ [])+  where+    ~(baseFunction₀, diffArguments₀) = go e₀++    go (App f a) = (baseFunction, diffArguments . (a :))+      where+        ~(baseFunction, diffArguments) = go f++    go (Note _ e) = go e++    go baseFunction = (baseFunction, id)++decodeExpressionInternal :: (Int -> Decoder s a) -> Decoder s (Expr t a)+decodeExpressionInternal decodeEmbed = go+  where+    go = do+        let die message = fail ("Dhall.Binary.decodeExpressionInternal: " <> message)++        tokenType₀ <- Decoding.peekTokenType++        case tokenType₀ of+            TypeUInt -> do+                !n <- Decoding.decodeWord++                return (Var (V "_" (fromIntegral n)))++            TypeUInt64 -> do+                !n <- Decoding.decodeWord64++                return (Var (V "_" (fromIntegral n)))++            TypeFloat16 -> do+                !n <- Decoding.decodeFloat++                return (DoubleLit (DhallDouble (float2Double n)))++            TypeFloat32 -> do+                !n <- Decoding.decodeFloat++                return (DoubleLit (DhallDouble (float2Double n)))++            TypeFloat64 -> do+                !n <- Decoding.decodeDouble++                return (DoubleLit (DhallDouble n))++            TypeBool -> do+                !b <- Decoding.decodeBool++                return (BoolLit b)++            TypeString -> do+                s <- Decoding.decodeString++                case s of+                    "Natural/build"     -> return NaturalBuild+                    "Natural/fold"      -> return NaturalFold+                    "Natural/isZero"    -> return NaturalIsZero+                    "Natural/even"      -> return NaturalEven+                    "Natural/odd"       -> return NaturalOdd+                    "Natural/toInteger" -> return NaturalToInteger+                    "Natural/show"      -> return NaturalShow+                    "Natural/subtract"  -> return NaturalSubtract+                    "Integer/toDouble"  -> return IntegerToDouble+                    "Integer/clamp"     -> return IntegerClamp+                    "Integer/negate"    -> return IntegerNegate+                    "Integer/show"      -> return IntegerShow+                    "Double/show"       -> return DoubleShow+                    "List/build"        -> return ListBuild+                    "List/fold"         -> return ListFold+                    "List/length"       -> return ListLength+                    "List/head"         -> return ListHead+                    "List/last"         -> return ListLast+                    "List/indexed"      -> return ListIndexed+                    "List/reverse"      -> return ListReverse+                    "Optional/fold"     -> return OptionalFold+                    "Optional/build"    -> return OptionalBuild+                    "Bool"              -> return Bool+                    "Optional"          -> return Optional+                    "None"              -> return None+                    "Natural"           -> return Natural+                    "Integer"           -> return Integer+                    "Double"            -> return Double+                    "Text"              -> return Text+                    "Text/show"         -> return TextShow+                    "List"              -> return List+                    "Type"              -> return (Const Type)+                    "Kind"              -> return (Const Kind)+                    "Sort"              -> return (Const Sort)+                    _                   -> die ("Unrecognized built-in: " <> Text.unpack s)++            TypeListLen -> do+                len <- Decoding.decodeListLen++                case len of+                    0 -> die "Missing tag"+                    _ -> return ()++                tokenType₁ <- Decoding.peekTokenType++                case tokenType₁ of+                    TypeString -> do+                        x <- Decoding.decodeString++                        if x == "_"+                            then die "Non-standard encoding of an α-normalized variable"+                            else return ()++                        tokenType₂ <- Decoding.peekTokenType++                        case tokenType₂ of+                            TypeUInt -> do+                                !n <- Decoding.decodeWord++                                return (Var (V x (fromIntegral n)))++                            TypeUInt64 -> do+                                !n <- Decoding.decodeWord64++                                return (Var (V x (fromIntegral n)))++                            _ -> do+                                die ("Unexpected token type for variable index: " <> show tokenType₂)++                    TypeUInt -> do+                        tag <- Decoding.decodeWord++                        case tag of+                            0 -> do+                                f <- go++                                xs <- Monad.replicateM (len - 2) go++                                if null xs+                                    then die "Non-standard encoding of a function with no arguments"+                                    else return ()++                                return (foldl' App f xs)++                            1 -> do+                                case len of+                                    3 -> do+                                        _A <- go++                                        b <- go++                                        return (Lam "_" _A b)++                                    4 -> do+                                        x <- Decoding.decodeString++                                        if x == "_"+                                            then die "Non-standard encoding of a λ expression"+                                            else return ()++                                        _A <- go++                                        b <- go++                                        return (Lam x _A b)++                                    _ -> do+                                        die ("Incorrect number of tokens used to encode a λ expression: " <> show len)++                            2 -> do+                                case len of+                                    3 -> do+                                        _A <- go++                                        _B <- go++                                        return (Pi "_" _A _B)++                                    4 -> do+                                        x <- Decoding.decodeString++                                        if x == "_"+                                            then die "Non-standard encoding of a ∀ expression"+                                            else return ()++                                        _A <- go++                                        _B <- go++                                        return (Pi x _A _B)++                                    _ -> do+                                        die ("Incorrect number of tokens used to encode a ∀ expression: " <> show len)++                            3 -> do+                                opcode <- Decoding.decodeWord++                                op <- case opcode of+                                    0  -> return BoolOr+                                    1  -> return BoolAnd+                                    2  -> return BoolEQ+                                    3  -> return BoolNE+                                    4  -> return NaturalPlus+                                    5  -> return NaturalTimes+                                    6  -> return TextAppend+                                    7  -> return ListAppend+                                    8  -> return Combine+                                    9  -> return Prefer+                                    10 -> return CombineTypes+                                    11 -> return ImportAlt+                                    12 -> return Equivalent+                                    13 -> return RecordCompletion+                                    _  -> die ("Unrecognized operator code: " <> show opcode)++                                l <- go++                                r <- go++                                return (op l r)++                            4 -> do+                                case len of+                                    2 -> do+                                        _T <- go++                                        return (ListLit (Just (App List _T)) empty)++                                    _ -> do+                                        Decoding.decodeNull++                                        xs <- Monad.replicateM (len - 2) go+                                        return (ListLit Nothing (Data.Sequence.fromList xs))++                            5 -> do+                                Decoding.decodeNull++                                t <- go++                                return (Some t)++                            6 -> do+                                t <- go++                                u <- go++                                case len of+                                    3 -> do+                                        return (Merge t u Nothing)++                                    4 -> do+                                        _T <- go++                                        return (Merge t u (Just _T))++                                    _ -> do+                                        die ("Incorrect number of tokens used to encode a `merge` expression: " <> show len)++                            7 -> do+                                mapLength <- Decoding.decodeMapLen++                                xTs <- Monad.replicateM mapLength $ do+                                    x <- Decoding.decodeString++                                    _T <- go++                                    return (x, _T)++                                return (Record (Dhall.Map.fromList xTs))++                            8 -> do+                                mapLength <- Decoding.decodeMapLen++                                xts <- Monad.replicateM mapLength $ do+                                    x <- Decoding.decodeString++                                    t <- go++                                    return (x, t)++                                return (RecordLit (Dhall.Map.fromList xts))++                            9 -> do+                                t <- go++                                x <- Decoding.decodeString++                                return (Field t x)++                            10 -> do+                                t <- go++                                xs <- case len of+                                    3 -> do+                                        tokenType₂ <- Decoding.peekTokenType++                                        case tokenType₂ of+                                            TypeListLen -> do+                                                _ <- Decoding.decodeListLen++                                                _T <- go++                                                return (Right _T)++                                            TypeString -> do+                                                x <- Decoding.decodeString+                                                return (Left (Dhall.Set.fromList [x]))++                                            _ -> do+                                                die ("Unexpected token type for projection: " <> show tokenType₂)++                                    _ -> do+                                        xs <- Monad.replicateM (len - 2) Decoding.decodeString++                                        return (Left (Dhall.Set.fromList xs))++                                return (Project t xs)++                            11 -> do+                                mapLength <- Decoding.decodeMapLen++                                xTs <- Monad.replicateM mapLength $ do+                                    x <- Decoding.decodeString++                                    tokenType₂ <- Decoding.peekTokenType++                                    mT <- case tokenType₂ of+                                        TypeNull -> do+                                            Decoding.decodeNull++                                            return Nothing++                                        _ -> do+                                            _T <- go++                                            return (Just _T)++                                    return (x, mT)++                                return (Union (Dhall.Map.fromList xTs))++                            14 -> do+                                t <- go++                                l <- go++                                r <- go++                                return (BoolIf t l r)++                            15 -> do+                                tokenType₂ <- Decoding.peekTokenType++                                case tokenType₂ of+                                    TypeUInt -> do+                                        n <- Decoding.decodeWord++                                        return (NaturalLit (fromIntegral n))++                                    TypeUInt64 -> do+                                        n <- Decoding.decodeWord64++                                        return (NaturalLit (fromIntegral n))++                                    TypeInteger -> do+                                        n <- Decoding.decodeInteger+                                        return (NaturalLit (fromIntegral n))++                                    _ -> do+                                        die ("Unexpected token type for Natural literal: " <> show tokenType₂)++                            16 -> do+                                tokenType₂ <- Decoding.peekTokenType++                                case tokenType₂ of+                                    TypeUInt -> do+                                        n <- Decoding.decodeWord++                                        return (IntegerLit (fromIntegral n))++                                    TypeUInt64 -> do+                                        n <- Decoding.decodeWord64++                                        return (IntegerLit (fromIntegral n))++                                    TypeNInt -> do+                                        n <- Decoding.decodeNegWord++                                        return (IntegerLit (-1 - fromIntegral n))++                                    TypeNInt64 -> do+                                        n <- Decoding.decodeNegWord64++                                        return (IntegerLit (-1 - fromIntegral n))+                                    TypeInteger -> do+                                        n <- Decoding.decodeInteger+                                        return (IntegerLit n)++                                    _ -> do+                                        die ("Unexpected token type for Integer literal: " <> show tokenType₂)++                            18 -> do+                                xys <- Monad.replicateM ((len - 2) `quot` 2) $ do+                                    x <- Decoding.decodeString++                                    y <- go++                                    return (x, y)++                                z <- Decoding.decodeString++                                return (TextLit (Chunks xys z))++                            19 -> do+                                t <- go++                                return (Assert t)++                            24 -> do+                                fmap Embed (decodeEmbed len)++                            25 -> do+                                bindings <- Monad.replicateM ((len - 2) `quot` 3) $ do+                                    x <- Decoding.decodeString++                                    tokenType₂ <- Decoding.peekTokenType++                                    mA <- case tokenType₂ of+                                        TypeNull -> do+                                            Decoding.decodeNull++                                            return Nothing++                                        _ -> do+                                            _A <- go++                                            return (Just (Nothing, _A))++                                    a <- go++                                    return (Binding Nothing x Nothing mA Nothing a)++                                b <- go++                                return (foldr Let b bindings)++                            26 -> do+                                t <- go++                                _T <- go++                                return (Annot t _T)++                            27 -> do+                                t <- go++                                mT <- case len of+                                    2 -> do+                                        return Nothing++                                    3 -> do+                                        _T <- go++                                        return (Just _T)++                                    _ -> do+                                        die ("Incorrect number of tokens used to encode a type annotation: " <> show len)++                                return (ToMap t mT)++                            28 -> do+                                _T <- go++                                return (ListLit (Just _T) empty)++                            _ -> do+                                die ("Unexpected tag: " <> show tag)++                    _ -> do+                        die ("Unexpected tag type: " <> show tokenType₁)++            _ -> do+                die ("Unexpected initial token: " <> show tokenType₀)++encodeExpressionInternal :: (a -> Encoding) -> Expr Void a -> Encoding+encodeExpressionInternal encodeEmbed = go+  where+    go e = case e of+        Var (V "_" n) ->+            Encoding.encodeInt n++        Var (V x n) ->+                Encoding.encodeListLen 2+            <>  Encoding.encodeString x+            <>  Encoding.encodeInt n++        NaturalBuild ->+            Encoding.encodeString "Natural/build"++        NaturalFold ->+            Encoding.encodeString "Natural/fold"++        NaturalIsZero ->+            Encoding.encodeString "Natural/isZero"++        NaturalEven ->+            Encoding.encodeString "Natural/even"++        NaturalOdd ->+            Encoding.encodeString "Natural/odd"++        NaturalToInteger ->+            Encoding.encodeString "Natural/toInteger"++        NaturalShow ->+            Encoding.encodeString "Natural/show"++        NaturalSubtract ->+            Encoding.encodeString "Natural/subtract"++        IntegerToDouble ->+            Encoding.encodeString "Integer/toDouble"++        IntegerClamp ->+            Encoding.encodeString "Integer/clamp"++        IntegerNegate ->+            Encoding.encodeString "Integer/negate"++        IntegerShow ->+            Encoding.encodeString "Integer/show"++        DoubleShow ->+            Encoding.encodeString "Double/show"++        ListBuild ->+            Encoding.encodeString "List/build"++        ListFold ->+            Encoding.encodeString "List/fold"++        ListLength ->+            Encoding.encodeString "List/length"++        ListHead ->+            Encoding.encodeString "List/head"++        ListLast ->+            Encoding.encodeString "List/last"++        ListIndexed ->+            Encoding.encodeString "List/indexed"++        ListReverse ->+            Encoding.encodeString "List/reverse"++        OptionalFold ->+            Encoding.encodeString "Optional/fold"++        OptionalBuild ->+            Encoding.encodeString "Optional/build"++        Bool ->+            Encoding.encodeString "Bool"++        Optional ->+            Encoding.encodeString "Optional"++        None ->+            Encoding.encodeString "None"++        Natural ->+            Encoding.encodeString "Natural"++        Integer ->+            Encoding.encodeString "Integer"++        Double ->+            Encoding.encodeString "Double"++        Text ->+            Encoding.encodeString "Text"++        TextShow ->+            Encoding.encodeString "Text/show"++        List ->+            Encoding.encodeString "List"++        Const Type ->+            Encoding.encodeString "Type"++        Const Kind ->+            Encoding.encodeString "Kind"++        Const Sort ->+            Encoding.encodeString "Sort"++        a@App{} ->+            encodeListN+                (2 + length arguments)+                ( Encoding.encodeInt 0+                : go function+                : map go arguments+                )+          where+            (function, arguments) = unApply a++        Lam "_" _A b ->+            encodeList3+                (Encoding.encodeInt 1)+                (go _A)+                (go b)++        Lam x _A b ->+            encodeList4+                (Encoding.encodeInt 1)+                (Encoding.encodeString x)+                (go _A)+                (go b)++        Pi "_" _A _B ->+            encodeList3+                (Encoding.encodeInt 2)+                (go _A)+                (go _B)++        Pi x _A _B ->+            encodeList4+                (Encoding.encodeInt 2)+                (Encoding.encodeString x)+                (go _A)+                (go _B)++        BoolOr l r ->+            encodeOperator 0 l r++        BoolAnd l r ->+            encodeOperator 1 l r++        BoolEQ l r ->+            encodeOperator 2 l r++        BoolNE l r ->+            encodeOperator 3 l r++        NaturalPlus l r ->+            encodeOperator 4 l r++        NaturalTimes l r ->+            encodeOperator 5 l r++        TextAppend l r ->+            encodeOperator 6 l r++        ListAppend l r ->+            encodeOperator 7 l r++        Combine l r ->+            encodeOperator 8 l r++        Prefer l r ->+            encodeOperator 9 l r++        CombineTypes l r ->+            encodeOperator 10 l r++        ImportAlt l r ->+            encodeOperator 11 l r++        Equivalent l r ->+            encodeOperator 12 l r++        RecordCompletion l r ->+            encodeOperator 13 l r++        ListLit _T₀ xs+            | null xs ->+                encodeList2 (Encoding.encodeInt label) _T₁+            | otherwise ->+                encodeListN+                    (2 + length xs)+                    ( Encoding.encodeInt 4+                    : Encoding.encodeNull+                    : map go (Data.Foldable.toList xs)+                    )+          where+            (label, _T₁) = case _T₀ of+                Nothing           -> (4 , Encoding.encodeNull)+                Just (App List t) -> (4 , go t               )+                Just  t           -> (28, go t               )++        Some t ->+            encodeList3+                (Encoding.encodeInt 5)+                Encoding.encodeNull+                (go t)++        Merge t u Nothing ->+            encodeList3+                (Encoding.encodeInt 6)+                (go t)+                (go u)++        Merge t u (Just _T) ->+            encodeList4+                (Encoding.encodeInt 6)+                (go t)+                (go u)+                (go _T)++        Record xTs ->+            encodeList2+                (Encoding.encodeInt 7)+                (encodeMapWith go xTs)++        RecordLit xts ->+            encodeList2+                (Encoding.encodeInt 8)+                (encodeMapWith go xts)++        Field t x ->+            encodeList3+                (Encoding.encodeInt 9)+                (go t)+                (Encoding.encodeString x)++        Project t (Left xs) ->+            encodeListN+                (2 + Dhall.Set.size xs)+                ( Encoding.encodeInt 10+                : go t+                : map Encoding.encodeString (Dhall.Set.toList xs)+                )++        Project t (Right _T) ->+            encodeList3+                (Encoding.encodeInt 10)+                (go t)+                (encodeList1 (go _T))++        Union xTs ->+            encodeList2+                (Encoding.encodeInt 11)+                (encodeMapWith encodeValue xTs)+          where+            encodeValue  Nothing  = Encoding.encodeNull+            encodeValue (Just _T) = go _T++        BoolLit b ->+            Encoding.encodeBool b++        BoolIf t l r ->+            encodeList4+                (Encoding.encodeInt 14)+                (go t)+                (go l)+                (go r)++        NaturalLit n ->+            encodeList2+                (Encoding.encodeInt 15)+                (Encoding.encodeInteger (fromIntegral n))++        IntegerLit n ->+            encodeList2+                (Encoding.encodeInt 16)+                (Encoding.encodeInteger (fromIntegral n))++        DoubleLit (DhallDouble n64)+            | useHalf   -> Encoding.encodeFloat16 n32+            | useFloat  -> Encoding.encodeFloat n32+            | otherwise -> Encoding.encodeDouble n64+          where+            n32 = double2Float n64++            useFloat = n64 == float2Double n32++            useHalf = n64 == 0.0 || n64 == infinity || n64 == -infinity++            infinity = 1/0 :: Double++        -- Fast path for the common case of an uninterpolated string+        TextLit (Chunks [] z) ->+            encodeList2+                (Encoding.encodeInt 18)+                (Encoding.encodeString z)++        TextLit (Chunks xys z) ->+            encodeListN+                (2 + 2 * length xys)+                ( Encoding.encodeInt 18+                : concatMap encodePair xys ++ [ Encoding.encodeString z ]+                )+          where+            encodePair (x, y) = [ Encoding.encodeString x, go y ]++        Assert t ->+            encodeList2+                (Encoding.encodeInt 19)+                (go t)++        Embed x ->+            encodeEmbed x++        Let a₀ b₀ ->+            encodeListN+                (2 + 3 * length as)+                ( Encoding.encodeInt 25+                : concatMap encodeBinding (toList as) ++ [ go b₁ ]+                )+          where+            MultiLet as b₁ = Dhall.Syntax.multiLet a₀ b₀++            encodeBinding (Binding _ x _ mA₀ _ a) =+                [ Encoding.encodeString x+                , mA₁+                , go a+                ]+              where+                mA₁ = case mA₀ of+                    Nothing      -> Encoding.encodeNull+                    Just (_, _A) -> go _A++        Annot t _T ->+            encodeList3+                (Encoding.encodeInt 26)+                (go t)+                (go _T)++        ToMap t Nothing ->+            encodeList2+                (Encoding.encodeInt 27)+                (go t)++        ToMap t (Just _T) ->+            encodeList3+                (Encoding.encodeInt 27)+                (go t)+                (go _T)++        Note _ b ->+            go b++    encodeOperator n l r =+        encodeList4+            (Encoding.encodeInt 3)+            (Encoding.encodeInt n)+            (go l)+            (go r)++    encodeMapWith encodeValue m =+            Encoding.encodeMapLen (fromIntegral (Dhall.Map.size m))+        <>  foldMap encodeKeyValue (Dhall.Map.toList (Dhall.Map.sort m))+      where+        encodeKeyValue (k, v) = Encoding.encodeString k <> encodeValue v++encodeList1 :: Encoding -> Encoding+encodeList1 a = Encoding.encodeListLen 1 <> a+{-# INLINE encodeList1 #-}++encodeList2 :: Encoding -> Encoding -> Encoding+encodeList2 a b = Encoding.encodeListLen 2 <> a <> b+{-# INLINE encodeList2 #-}++encodeList3 :: Encoding -> Encoding -> Encoding -> Encoding+encodeList3 a b c = Encoding.encodeListLen 3 <> a <> b <> c+{-# INLINE encodeList3 #-}++encodeList4 :: Encoding -> Encoding -> Encoding -> Encoding -> Encoding+encodeList4 a b c d = Encoding.encodeListLen 4 <> a <> b <> c <> d+{-# INLINE encodeList4 #-}++encodeListN :: Int -> [ Encoding ] -> Encoding+encodeListN len xs = Encoding.encodeListLen (fromIntegral len) <> mconcat xs+{-# INLINE encodeListN #-}++encodeList :: [ Encoding ] -> Encoding+encodeList xs = encodeListN (length xs) xs+{-# INLINE encodeList #-}++decodeImport :: Int -> Decoder s Import+decodeImport len = do+    let die message = fail ("Dhall.Binary.decodeImport: " <> message)++    tokenType₀ <- Decoding.peekTokenType++    hash <- case tokenType₀ of+        TypeNull -> do+            Decoding.decodeNull++            return Nothing++        TypeBytes -> do+            bytes <- Decoding.decodeBytes++            let (prefix, suffix) = Data.ByteString.splitAt 2 bytes++            case prefix of+                "\x12\x20" -> return ()+                _          -> die ("Unrecognized multihash prefix: " <> show prefix)+            case Dhall.Crypto.sha256DigestFromByteString suffix of+                Nothing     -> die ("Invalid sha256 digest: " <> show bytes)+                Just digest -> return (Just digest)++        _ -> do+            die ("Unexpected hash token: " <> show tokenType₀)++    m <- Decoding.decodeWord++    importMode <- case m of+        0 -> return Code+        1 -> return RawText+        2 -> return Location+        _ -> die ("Unexpected code for import mode: " <> show m)++    let remote scheme = do+            tokenType₁ <- Decoding.peekTokenType++            headers <- case tokenType₁ of+                TypeNull -> do+                    Decoding.decodeNull+                    return Nothing++                _ -> do+                    headers <- decodeExpressionInternal decodeImport++                    return (Just headers)++            authority <- Decoding.decodeString++            paths <- Monad.replicateM (len - 8) Decoding.decodeString++            file <- Decoding.decodeString++            tokenType₂ <- Decoding.peekTokenType++            query <- case tokenType₂ of+                TypeNull -> do+                    Decoding.decodeNull+                    return Nothing+                _ -> do+                    fmap Just Decoding.decodeString++            let components = reverse paths+            let directory  = Directory {..}+            let path       = File {..}++            return (Remote (URL {..}))++    let local prefix = do+            paths <- Monad.replicateM (len - 5) Decoding.decodeString++            file <- Decoding.decodeString++            let components = reverse paths+            let directory  = Directory {..}++            return (Local prefix (File {..}))++    let missing = return Missing++    let env = do+            x <- Decoding.decodeString++            return (Env x)++    n <- Decoding.decodeWord++    importType <- case n of+        0 -> remote HTTP+        1 -> remote HTTPS+        2 -> local Absolute+        3 -> local Here+        4 -> local Parent+        5 -> local Home+        6 -> env+        7 -> missing+        _ -> fail ("Unrecognized import type code: " <> show n)++    let importHashed = ImportHashed {..}++    return (Import {..})++encodeImport :: Import -> Encoding+encodeImport import_ =+    case importType of+        Remote (URL { scheme = scheme₀, .. }) ->+            encodeList+                (   prefix+                ++  [ Encoding.encodeInt scheme₁+                    , using+                    , Encoding.encodeString authority+                    ]+                ++  map Encoding.encodeString (reverse components)+                ++  [ Encoding.encodeString file ]+                ++  [ case query of+                         Nothing -> Encoding.encodeNull+                         Just q  -> Encoding.encodeString q+                    ]+                )+          where+            using = case headers of+                Nothing ->+                    Encoding.encodeNull+                Just h ->+                    encodeExpressionInternal encodeImport (Dhall.Syntax.denote h)++            scheme₁ = case scheme₀ of+                HTTP  -> 0+                HTTPS -> 1++            File{..} = path++            Directory {..} = directory++        Local prefix₀ path ->+            encodeList+                (   prefix+                ++  [ Encoding.encodeInt prefix₁ ]+                ++  map Encoding.encodeString components₁+                ++  [ Encoding.encodeString file ]+                )+          where+            File{..} = path++            Directory{..} = directory++            prefix₁ = case prefix₀ of+                Absolute -> 2+                Here     -> 3+                Parent   -> 4+                Home     -> 5++            components₁ = reverse components++        Env x ->+            encodeList+                (prefix ++ [ Encoding.encodeInt 6, Encoding.encodeString x ])++        Missing ->+            encodeList (prefix ++ [ Encoding.encodeInt 7 ])+  where+    prefix = [ Encoding.encodeInt 24, h, m ]+      where+        h = case hash of+            Nothing ->+                Encoding.encodeNull++            Just digest ->+                Encoding.encodeBytes ("\x12\x20" <> Data.ByteArray.convert digest)++        m = Encoding.encodeInt (case importMode of Code -> 0; RawText -> 1; Location -> 2;)++    Import{..} = import_++    ImportHashed{..} = importHashed++decodeVoid :: Int -> Decoder s Void+decodeVoid _ = fail "Dhall.Binary.decodeVoid: Cannot decode an uninhabited type"++encodeVoid :: Void -> Encoding+encodeVoid = absurd++instance Serialise (Expr Void Void) where+    encode = encodeExpressionInternal encodeVoid++    decode = decodeExpressionInternal decodeVoid++instance Serialise (Expr Void Import) where+    encode = encodeExpressionInternal encodeImport++    decode = decodeExpressionInternal decodeImport++-- | Encode a Dhall expression as a CBOR-encoded `ByteString`+encodeExpression :: Expr Void Import -> ByteString+encodeExpression = Serialise.serialise++-- | Decode a Dhall expression from a CBOR `Term`+decodeExpression+    :: Serialise (Expr s a) => ByteString -> Either DecodingFailure (Expr s a)+decodeExpression bytes =+    case decodeWithoutVersion <|> decodeWithVersion of+        Just expression -> Right expression+        Nothing         -> Left (CBORIsNotDhall bytes)+  where+    adapt (Right ("", x)) = Just x+    adapt  _              = Nothing++    decode' = decodeWith55799Tag decode++    -- This is the behavior specified by the standard+    decodeWithoutVersion = adapt (Read.deserialiseFromBytes decode' bytes)++    -- tag to ease the migration+    decodeWithVersion = adapt (Read.deserialiseFromBytes decodeWithTag bytes)+      where+        decodeWithTag = do+            2 <- Decoding.decodeListLen++            version <- Decoding.decodeString+++            -- "_" has never been a valid version string, and this ensures that+            -- we don't interpret `[ "_", 0 ]` as the expression `_` (encoded as+            -- `0`) tagged with a version string of `"_"`+            if (version == "_")+                then fail "Dhall.Binary.decodeExpression: \"_\" is not a valid version string"+                else return ()++            decode'++decodeWith55799Tag :: Decoder s a -> Decoder s a+decodeWith55799Tag decoder = do+    tokenType <- Decoding.peekTokenType++    case tokenType of+        TypeTag -> do+            w <- Decoding.decodeTag++            if w /= 55799+                then fail ("Dhall.Binary.decodeWith55799Tag: Unexpected tag: " <> show w)+                else return ()++            decoder+        _ -> do+            decoder++{-| This indicates that a given CBOR-encoded `ByteString` did not correspond to+    a valid Dhall expression+-}+newtype DecodingFailure = CBORIsNotDhall ByteString+    deriving (Eq)++instance Exception DecodingFailure++_ERROR :: String+_ERROR = "\ESC[1;31mError\ESC[0m"++instance Show DecodingFailure where+    show (CBORIsNotDhall bytes) =+            _ERROR <> ": Cannot decode CBOR to Dhall\n"+        <>  "\n"+        <>  "The following bytes do not encode a valid Dhall expression\n"+        <>  "\n"+        <>  "↳ 0x" <> concatMap toHex (Data.ByteString.Lazy.unpack bytes) <> "\n"+      where+        toHex = Printf.printf "%02x "
src/Dhall/Core.hs view
@@ -1,1306 +1,89 @@-{-# LANGUAGE BangPatterns       #-}-{-# LANGUAGE LambdaCase         #-}-{-# LANGUAGE OverloadedStrings  #-}-{-# LANGUAGE RankNTypes         #-}-{-# LANGUAGE RecordWildCards    #-}--{-| This module contains the core calculus for the Dhall language.--    Dhall is essentially a fork of the @morte@ compiler but with more built-in-    functionality, better error messages, and Haskell integration--}--module Dhall.Core (-    -- * Syntax-      Const(..)-    , Directory(..)-    , File(..)-    , FilePrefix(..)-    , Import(..)-    , ImportHashed(..)-    , ImportMode(..)-    , ImportType(..)-    , URL(..)-    , Scheme(..)-    , DhallDouble(..)-    , Var(..)-    , Binding(..)-    , makeBinding-    , Chunks(..)-    , Expr(..)--    -- * Normalization-    , alphaNormalize-    , normalize-    , normalizeWith-    , normalizeWithM-    , Normalizer-    , NormalizerM-    , ReifiedNormalizer (..)-    , judgmentallyEqual-    , subst-    , shift-    , isNormalized-    , isNormalizedWith-    , denote-    , renote-    , shallowDenote-    , freeIn--    -- * Pretty-printing-    , pretty--    -- * Optics-    , subExpressions-    , chunkExprs-    , bindingExprs--    -- * Let-blocks-    , multiLet-    , wrapInLets-    , MultiLet(..)--    -- * Miscellaneous-    , internalError-    , reservedIdentifiers-    , escapeText-    , pathCharacter-    , throws-    , Eval.textShow-    , censorExpression-    , censorText-    ) where--import Control.Applicative (empty)-import Control.Exception (Exception)-import Control.Monad.IO.Class (MonadIO(..))-import Data.Foldable-import Data.Functor.Identity (Identity(..))-import Data.Semigroup (Semigroup(..))-import Data.Sequence (ViewL(..), ViewR(..))-import Data.Text (Text)-import Data.Text.Prettyprint.Doc (Pretty)-import Data.Traversable-import Dhall.Src (Src(..))-import Dhall.Syntax-import Dhall.Pretty.Internal-import Instances.TH.Lift ()-import Lens.Family (over)-import Prelude hiding (succ)--import qualified Control.Exception-import qualified Dhall.Eval    as Eval-import qualified Data.Sequence-import qualified Data.Set-import qualified Data.Text-import qualified Dhall.Map-import qualified Dhall.Set--{-| Returns `True` if two expressions are α-equivalent and β-equivalent and-    `False` otherwise--    `judgmentallyEqual` can fail with an `error` if you compare ill-typed-    expressions--}-judgmentallyEqual :: Eq a => Expr s a -> Expr t a -> Bool-judgmentallyEqual = Eval.judgmentallyEqual-{-# INLINE judgmentallyEqual #-}--{-| `shift` is used by both normalization and type-checking to avoid variable-    capture by shifting variable indices--    For example, suppose that you were to normalize the following expression:--> λ(a : Type) → λ(x : a) → (λ(y : a) → λ(x : a) → y) x--    If you were to substitute @y@ with @x@ without shifting any variable-    indices, then you would get the following incorrect result:--> λ(a : Type) → λ(x : a) → λ(x : a) → x  -- Incorrect normalized form--    In order to substitute @x@ in place of @y@ we need to `shift` @x@ by @1@ in-    order to avoid being misinterpreted as the @x@ bound by the innermost-    lambda.  If we perform that `shift` then we get the correct result:--> λ(a : Type) → λ(x : a) → λ(x : a) → x@1--    As a more worked example, suppose that you were to normalize the following-    expression:-->     λ(a : Type)-> →   λ(f : a → a → a)-> →   λ(x : a)-> →   λ(x : a)-> →   (λ(x : a) → f x x@1) x@1--    The correct normalized result would be:-->     λ(a : Type)-> →   λ(f : a → a → a)-> →   λ(x : a)-> →   λ(x : a)-> →   f x@1 x--    The above example illustrates how we need to both increase and decrease-    variable indices as part of substitution:--    * We need to increase the index of the outer @x\@1@ to @x\@2@ before we-      substitute it into the body of the innermost lambda expression in order-      to avoid variable capture.  This substitution changes the body of the-      lambda expression to @(f x\@2 x\@1)@--    * We then remove the innermost lambda and therefore decrease the indices of-      both @x@s in @(f x\@2 x\@1)@ to @(f x\@1 x)@ in order to reflect that one-      less @x@ variable is now bound within that scope--    Formally, @(shift d (V x n) e)@ modifies the expression @e@ by adding @d@ to-    the indices of all variables named @x@ whose indices are greater than-    @(n + m)@, where @m@ is the number of bound variables of the same name-    within that scope--    In practice, @d@ is always @1@ or @-1@ because we either:--    * increment variables by @1@ to avoid variable capture during substitution-    * decrement variables by @1@ when deleting lambdas after substitution--    @n@ starts off at @0@ when substitution begins and increments every time we-    descend into a lambda or let expression that binds a variable of the same-    name in order to avoid shifting the bound variables by mistake.--}-shift :: Int -> Var -> Expr s a -> Expr s a-shift _ _ (Const a) = Const a-shift d (V x n) (Var (V x' n')) = Var (V x' n'')-  where-    n'' = if x == x' && n <= n' then n' + d else n'-shift d (V x n) (Lam x' _A b) = Lam x' _A' b'-  where-    _A' = shift d (V x n ) _A-    b'  = shift d (V x n') b-      where-        n' = if x == x' then n + 1 else n-shift d (V x n) (Pi x' _A _B) = Pi x' _A' _B'-  where-    _A' = shift d (V x n ) _A-    _B' = shift d (V x n') _B-      where-        n' = if x == x' then n + 1 else n-shift d v (App f a) = App f' a'-  where-    f' = shift d v f-    a' = shift d v a-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 (Annot a b) = Annot a' b'-  where-    a' = shift d v a-    b' = shift d v b-shift _ _ Bool = Bool-shift _ _ (BoolLit a) = BoolLit a-shift d v (BoolAnd a b) = BoolAnd a' b'-  where-    a' = shift d v a-    b' = shift d v b-shift d v (BoolOr a b) = BoolOr a' b'-  where-    a' = shift d v a-    b' = shift d v b-shift d v (BoolEQ a b) = BoolEQ a' b'-  where-    a' = shift d v a-    b' = shift d v b-shift d v (BoolNE a b) = BoolNE a' b'-  where-    a' = shift d v a-    b' = shift d v b-shift d v (BoolIf a b c) = BoolIf a' b' c'-  where-    a' = shift d v a-    b' = shift d v b-    c' = shift d v c-shift _ _ Natural = Natural-shift _ _ (NaturalLit a) = NaturalLit a-shift _ _ NaturalFold = NaturalFold-shift _ _ NaturalBuild = NaturalBuild-shift _ _ NaturalIsZero = NaturalIsZero-shift _ _ NaturalEven = NaturalEven-shift _ _ NaturalOdd = NaturalOdd-shift _ _ NaturalToInteger = NaturalToInteger-shift _ _ NaturalShow = NaturalShow-shift _ _ NaturalSubtract = NaturalSubtract-shift d v (NaturalPlus a b) = NaturalPlus a' b'-  where-    a' = shift d v a-    b' = shift d v b-shift d v (NaturalTimes a b) = NaturalTimes a' b'-  where-    a' = shift d v a-    b' = shift d v b-shift _ _ Integer = Integer-shift _ _ (IntegerLit a) = IntegerLit a-shift _ _ IntegerShow = IntegerShow-shift _ _ IntegerToDouble = IntegerToDouble-shift _ _ Double = Double-shift _ _ (DoubleLit a) = DoubleLit a-shift _ _ DoubleShow = DoubleShow-shift _ _ Text = Text-shift d v (TextLit (Chunks a b)) = TextLit (Chunks a' b)-  where-    a' = fmap (fmap (shift d v)) a-shift d v (TextAppend a b) = TextAppend a' b'-  where-    a' = shift d v a-    b' = shift d v b-shift _ _ TextShow = TextShow-shift _ _ List = List-shift d v (ListLit a b) = ListLit a' b'-  where-    a' = fmap (shift d v) a-    b' = fmap (shift d v) b-shift _ _ ListBuild = ListBuild-shift d v (ListAppend a b) = ListAppend a' b'-  where-    a' = shift d v a-    b' = shift d v b-shift _ _ ListFold = ListFold-shift _ _ ListLength = ListLength-shift _ _ ListHead = ListHead-shift _ _ ListLast = ListLast-shift _ _ ListIndexed = ListIndexed-shift _ _ ListReverse = ListReverse-shift _ _ Optional = Optional-shift d v (Some a) = Some a'-  where-    a' = shift d v a-shift _ _ None = None-shift _ _ OptionalFold = OptionalFold-shift _ _ OptionalBuild = OptionalBuild-shift d v (Record a) = Record a'-  where-    a' = fmap (shift d v) a-shift d v (RecordLit a) = RecordLit a'-  where-    a' = fmap (shift d v) a-shift d v (Union a) = Union a'-  where-    a' = fmap (fmap (shift d v)) a-shift d v (Combine a b) = Combine a' b'-  where-    a' = shift d v a-    b' = shift d v b-shift d v (CombineTypes a b) = CombineTypes a' b'-  where-    a' = shift d v a-    b' = shift d v b-shift d v (Prefer a b) = Prefer a' b'-  where-    a' = shift d v a-    b' = shift d v b-shift d v (RecordCompletion a b) = RecordCompletion a' b'-  where-    a' = shift d v a-    b' = shift d v b-shift d v (Merge a b c) = Merge a' b' c'-  where-    a' =       shift d v  a-    b' =       shift d v  b-    c' = fmap (shift d v) c-shift d v (ToMap a b) = ToMap a' b'-  where-    a' =       shift d v  a-    b' = fmap (shift d v) b-shift d v (Field a b) = Field a' b-  where-    a' = shift d v a-shift d v (Assert a) = Assert a'-  where-    a' = shift d v a-shift d v (Equivalent a b) = Equivalent a' b'-  where-    a' = shift d v a-    b' = shift d v b-shift d v (Project a b) = Project a' b'-  where-    a' =       shift d v  a-    b' = fmap (shift d v) b-shift d v (Note a b) = Note a b'-  where-    b' = shift d v b-shift d v (ImportAlt a b) = ImportAlt a' b'-  where-    a' = shift d v a-    b' = shift d v b--- The Dhall compiler enforces that all embedded values are closed expressions--- and `shift` does nothing to a closed expression-shift _ _ (Embed p) = Embed p--{-| Substitute all occurrences of a variable with an expression--> subst x C B  ~  B[x := C]--}-subst :: Var -> Expr s a -> Expr s a -> Expr s a-subst _ _ (Const a) = Const a-subst (V x n) e (Lam y _A b) = Lam y _A' b'-  where-    _A' = subst (V x n )                  e  _A-    b'  = subst (V x n') (shift 1 (V y 0) e)  b-    n'  = if x == y then n + 1 else n-subst (V x n) e (Pi y _A _B) = Pi y _A' _B'-  where-    _A' = subst (V x n )                  e  _A-    _B' = subst (V x n') (shift 1 (V y 0) e) _B-    n'  = if x == y then n + 1 else n-subst v e (App f a) = App f' a'-  where-    f' = subst v e f-    a' = subst v e a-subst v e (Var v') = if v == v' then e else Var v'-subst (V x n) e (Let (Binding src0 f src1 mt src2 r) b) =-    Let (Binding src0 f src1 mt' src2 r') b'-  where-    b' = subst (V x n') (shift 1 (V f 0) e) b-      where-        n' = if x == f then n + 1 else n--    mt' = fmap (fmap (subst (V x n) e)) mt-    r'  =             subst (V x n) e  r-subst x e (Annot a b) = Annot a' b'-  where-    a' = subst x e a-    b' = subst x e b-subst _ _ Bool = Bool-subst _ _ (BoolLit a) = BoolLit a-subst x e (BoolAnd a b) = BoolAnd a' b'-  where-    a' = subst x e a-    b' = subst x e b-subst x e (BoolOr a b) = BoolOr a' b'-  where-    a' = subst x e a-    b' = subst x e b-subst x e (BoolEQ a b) = BoolEQ a' b'-  where-    a' = subst x e a-    b' = subst x e b-subst x e (BoolNE a b) = BoolNE a' b'-  where-    a' = subst x e a-    b' = subst x e b-subst x e (BoolIf a b c) = BoolIf a' b' c'-  where-    a' = subst x e a-    b' = subst x e b-    c' = subst x e c-subst _ _ Natural = Natural-subst _ _ (NaturalLit a) = NaturalLit a-subst _ _ NaturalFold = NaturalFold-subst _ _ NaturalBuild = NaturalBuild-subst _ _ NaturalIsZero = NaturalIsZero-subst _ _ NaturalEven = NaturalEven-subst _ _ NaturalOdd = NaturalOdd-subst _ _ NaturalToInteger = NaturalToInteger-subst _ _ NaturalShow = NaturalShow-subst _ _ NaturalSubtract = NaturalSubtract-subst x e (NaturalPlus a b) = NaturalPlus a' b'-  where-    a' = subst x e a-    b' = subst x e b-subst x e (NaturalTimes a b) = NaturalTimes a' b'-  where-    a' = subst x e a-    b' = subst x e b-subst _ _ Integer = Integer-subst _ _ (IntegerLit a) = IntegerLit a-subst _ _ IntegerShow = IntegerShow-subst _ _ IntegerToDouble = IntegerToDouble-subst _ _ Double = Double-subst _ _ (DoubleLit a) = DoubleLit a-subst _ _ DoubleShow = DoubleShow-subst _ _ Text = Text-subst x e (TextLit (Chunks a b)) = TextLit (Chunks a' b)-  where-    a' = fmap (fmap (subst x e)) a-subst x e (TextAppend a b) = TextAppend a' b'-  where-    a' = subst x e a-    b' = subst x e b-subst _ _ TextShow = TextShow-subst _ _ List = List-subst x e (ListLit a b) = ListLit a' b'-  where-    a' = fmap (subst x e) a-    b' = fmap (subst x e) b-subst x e (ListAppend a b) = ListAppend a' b'-  where-    a' = subst x e a-    b' = subst x e b-subst _ _ ListBuild = ListBuild-subst _ _ ListFold = ListFold-subst _ _ ListLength = ListLength-subst _ _ ListHead = ListHead-subst _ _ ListLast = ListLast-subst _ _ ListIndexed = ListIndexed-subst _ _ ListReverse = ListReverse-subst _ _ Optional = Optional-subst x e (Some a) = Some a'-  where-    a' = subst x e a-subst _ _ None = None-subst _ _ OptionalFold = OptionalFold-subst _ _ OptionalBuild = OptionalBuild-subst x e (Record kts) = Record kts'-  where-    kts' = fmap (subst x e) kts-subst x e (RecordLit kvs) = RecordLit kvs'-  where-    kvs' = fmap (subst x e) kvs-subst x e (Union kts) = Union kts'-  where-    kts' = fmap (fmap (subst x e)) kts-subst x e (Combine a b) = Combine a' b'-  where-    a' = subst x e a-    b' = subst x e b-subst x e (CombineTypes a b) = CombineTypes a' b'-  where-    a' = subst x e a-    b' = subst x e b-subst x e (Prefer a b) = Prefer a' b'-  where-    a' = subst x e a-    b' = subst x e b-subst x e (RecordCompletion a b) = RecordCompletion a' b'-  where-    a' = subst x e a-    b' = subst x e b-subst x e (Merge a b c) = Merge a' b' c'-  where-    a' =       subst x e  a-    b' =       subst x e  b-    c' = fmap (subst x e) c-subst x e (ToMap a b) = ToMap a' b'-  where-    a' =       subst x e  a-    b' = fmap (subst x e) b-subst x e (Field a b) = Field a' b-  where-    a' = subst x e a-subst x e (Project a b) = Project a' b'-  where-    a' =       subst x e  a-    b' = fmap (subst x e) b-subst x e (Assert a) = Assert a'-  where-    a' = subst x e a-subst x e (Equivalent a b) = Equivalent a' b'-  where-    a' = subst x e a-    b' = subst x e b-subst x e (Note a b) = Note a b'-  where-    b' = subst x e b-subst x e (ImportAlt a b) = ImportAlt a' b'-  where-    a' = subst x e a-    b' = subst x e b--- The Dhall compiler enforces that all embedded values are closed expressions--- and `subst` does nothing to a closed expression-subst _ _ (Embed p) = Embed p--{-| This function is used to determine whether folds like @Natural/fold@ or-    @List/fold@ should be lazy or strict in their accumulator based on the type-    of the accumulator--    If this function returns `True`, then they will be strict in their-    accumulator since we can guarantee an upper bound on the amount of work to-    normalize the accumulator on each step of the loop.  If this function-    returns `False` then they will be lazy in their accumulator and only-    normalize the final result at the end of the fold--}-boundedType :: Expr s a -> Bool-boundedType Bool             = True-boundedType Natural          = True-boundedType Integer          = True-boundedType Double           = True-boundedType Text             = True-boundedType (App List _)     = False-boundedType (App Optional t) = boundedType t-boundedType (Record kvs)     = all boundedType kvs-boundedType (Union kvs)      = all (all boundedType) kvs-boundedType _                = False--{-| α-normalize an expression by renaming all bound variables to @\"_\"@ and-    using De Bruijn indices to distinguish them-->>> alphaNormalize (Lam "a" (Const Type) (Lam "b" (Const Type) (Lam "x" "a" (Lam "y" "b" "x"))))-Lam "_" (Const Type) (Lam "_" (Const Type) (Lam "_" (Var (V "_" 1)) (Lam "_" (Var (V "_" 1)) (Var (V "_" 1)))))--    α-normalization does not affect free variables:-->>> alphaNormalize "x"-Var (V "x" 0)---}-alphaNormalize :: Expr s a -> Expr s a-alphaNormalize = Eval.alphaNormalize-{-# INLINE alphaNormalize #-}--{-| Reduce an expression to its normal form, performing beta reduction--    `normalize` does not type-check the expression.  You may want to type-check-    expressions before normalizing them since normalization can convert an-    ill-typed expression into a well-typed expression.--    `normalize` can also fail with `error` if you normalize an ill-typed-    expression--}-normalize :: Eq a => Expr s a -> Expr t a-normalize = Eval.normalize-{-# INLINE normalize #-}--{-| Reduce an expression to its normal form, performing beta reduction and applying-    any custom definitions.--    `normalizeWith` is designed to be used with function `typeWith`. The `typeWith`-    function allows typing of Dhall functions in a custom typing context whereas-    `normalizeWith` allows evaluating Dhall expressions in a custom context.--    To be more precise `normalizeWith` applies the given normalizer when it finds an-    application term that it cannot reduce by other means.--    Note that the context used in normalization will determine the properties of normalization.-    That is, if the functions in custom context are not total then the Dhall language, evaluated-    with those functions is not total either.--    `normalizeWith` can fail with an `error` if you normalize an ill-typed-    expression--}-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--{-| This function generalizes `normalizeWith` by allowing the custom normalizer-    to use an arbitrary `Monad`--    `normalizeWithM` can fail with an `error` if you normalize an ill-typed-    expression--}-normalizeWithM-    :: (Monad m, Eq a) => NormalizerM m a -> Expr s a -> m (Expr t a)-normalizeWithM ctx e0 = loop (denote e0)- where- loop e =  case e of-    Const k -> pure (Const k)-    Var v -> pure (Var v)-    Lam x _A b -> Lam 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-              f' <- loop f-              a' <- loop a-              case f' of-                Lam x _A b₀ -> do--                    let a₂ = shift 1 (V x 0) a'-                    let b₁ = subst (V x 0) a₂ b₀-                    let b₂ = shift (-1) (V x 0) b₁--                    loop b₂-                _ -> do-                  case App f' a' of-                    -- build/fold fusion for `List`-                    App (App ListBuild _) (App (App ListFold _) e') -> loop e'--                    App NaturalFold (NaturalLit n) -> do-                        let natural = Var (V "natural" 0)-                        let go 0  x = x-                            go n' x = go (n'-1) (App (Var (V "succ" 0)) x)-                        let n' = go n (Var (V "zero" 0))-                        pure-                            (Lam "natural"-                                (Const Type)-                                (Lam "succ"-                                    (Pi "_" natural natural)-                                    (Lam "zero"-                                        natural-                                        n')))--                    -- build/fold fusion for `Natural`-                    App NaturalBuild (App NaturalFold e') -> loop e'--                    -- build/fold fusion for `Optional`-                    App (App OptionalBuild _) (App (App OptionalFold _) e') -> loop e'--                    App (App (App (App NaturalFold (NaturalLit n0)) t) succ') zero -> do-                      t' <- loop t-                      if boundedType t' then strict else lazy-                      where-                        strict =       strictLoop (fromIntegral n0 :: Integer)-                        lazy   = loop (  lazyLoop (fromIntegral n0 :: Integer))--                        strictLoop !0 = loop zero-                        strictLoop !n = App succ' <$> strictLoop (n - 1) >>= loop--                        lazyLoop !0 = zero-                        lazyLoop !n = App succ' (lazyLoop (n - 1))-                    App NaturalBuild g -> loop (App (App (App g Natural) succ) zero)-                      where-                        succ = Lam "n" Natural (NaturalPlus "n" (NaturalLit 1))--                        zero = NaturalLit 0-                    App NaturalIsZero (NaturalLit n) -> pure (BoolLit (n == 0))-                    App NaturalEven (NaturalLit n) -> pure (BoolLit (even n))-                    App NaturalOdd (NaturalLit n) -> pure (BoolLit (odd n))-                    App NaturalToInteger (NaturalLit n) -> pure (IntegerLit (toInteger n))-                    App NaturalShow (NaturalLit n) ->-                        pure (TextLit (Chunks [] (Data.Text.pack (show n))))-                    App (App NaturalSubtract (NaturalLit x)) (NaturalLit y)-                        | y >= x    -> pure (NaturalLit (subtract x y))-                        | otherwise -> pure (NaturalLit 0)-                    App (App NaturalSubtract (NaturalLit 0)) y -> pure y-                    App (App NaturalSubtract _) (NaturalLit 0) -> pure (NaturalLit 0)-                    App (App NaturalSubtract x) y | Eval.judgmentallyEqual x y -> pure (NaturalLit 0)-                    App IntegerShow (IntegerLit n)-                        | 0 <= n    -> pure (TextLit (Chunks [] ("+" <> Data.Text.pack (show n))))-                        | otherwise -> pure (TextLit (Chunks [] (Data.Text.pack (show n))))-                    -- `(read . show)` is used instead of `fromInteger` because `read` uses-                    -- the correct rounding rule.-                    -- See https://gitlab.haskell.org/ghc/ghc/issues/17231.-                    App IntegerToDouble (IntegerLit n) -> pure (DoubleLit ((DhallDouble . read . show) n))-                    App DoubleShow (DoubleLit (DhallDouble n)) ->-                        pure (TextLit (Chunks [] (Data.Text.pack (show n))))-                    App (App OptionalBuild _A₀) g ->-                        loop (App (App (App g optional) just) nothing)-                      where-                        optional = App Optional _A₀--                        just = Lam "a" _A₀ (Some "a")--                        nothing = App None _A₀-                    App (App ListBuild _A₀) g -> loop (App (App (App g list) cons) nil)-                      where-                        _A₁ = shift 1 "a" _A₀--                        list = App List _A₀--                        cons =-                            Lam "a" _A₀-                                (Lam "as"-                                    (App List _A₁)-                                    (ListAppend (ListLit Nothing (pure "a")) "as")-                                )--                        nil = ListLit (Just (App List _A₀)) empty-                    App (App ListFold t) (ListLit _ xs) -> do-                        t' <- loop t-                        let list = Var (V "list" 0)-                        let lam term =-                                Lam "list" (Const Type)-                                    (Lam "cons" (Pi "_" t' (Pi "_" list list))-                                        (Lam "nil" list term))-                        term <- foldrM-                            (\x acc -> do-                                x' <- loop x-                                pure (App (App (Var (V "cons" 0)) x') acc))-                            (Var (V "nil" 0))-                            xs-                        pure (lam term)-                    App (App (App (App (App ListFold _) (ListLit _ xs)) t) cons) nil -> do-                      t' <- loop t-                      if boundedType t' then strict else lazy-                      where-                        strict =       foldr strictCons strictNil xs-                        lazy   = loop (foldr   lazyCons   lazyNil xs)--                        strictNil = loop nil-                        lazyNil   =      nil--                        strictCons y ys = do-                          App (App cons y) <$> ys >>= loop-                        lazyCons   y ys =       App (App cons y) ys-                    App (App ListLength _) (ListLit _ ys) ->-                        pure (NaturalLit (fromIntegral (Data.Sequence.length ys)))-                    App (App ListHead t) (ListLit _ ys) -> loop o-                      where-                        o = case Data.Sequence.viewl ys of-                                y :< _ -> Some y-                                _      -> App None t-                    App (App ListLast t) (ListLit _ ys) -> loop o-                      where-                        o = case Data.Sequence.viewr ys of-                                _ :> y -> Some y-                                _      -> App None t-                    App (App ListIndexed _A₀) (ListLit _ as₀) -> loop (ListLit t as₁)-                      where-                        as₁ = Data.Sequence.mapWithIndex adapt as₀--                        _A₂ = Record (Dhall.Map.fromList kts)-                          where-                            kts = [ ("index", Natural)-                                  , ("value", _A₀)-                                  ]--                        t | null as₀  = Just (App List _A₂)-                          | otherwise = Nothing--                        adapt n a_ =-                            RecordLit (Dhall.Map.fromList kvs)-                          where-                            kvs = [ ("index", NaturalLit (fromIntegral n))-                                  , ("value", a_)-                                  ]-                    App (App ListReverse _) (ListLit t xs) ->-                        loop (ListLit t (Data.Sequence.reverse xs))--                    App (App OptionalFold t0) x0 -> do-                        t1 <- loop t0-                        let optional = Var (V "optional" 0)-                        let lam term = (Lam "optional"-                                           (Const Type)-                                           (Lam "some"-                                               (Pi "_" t1 optional)-                                               (Lam "none" optional term)))-                        x1 <- loop x0-                        pure $ case x1 of-                            App None _ -> lam (Var (V "none" 0))-                            Some x'    -> lam (App (Var (V "some" 0)) x')-                            _          -> App (App OptionalFold t1) x1--                    App TextShow (TextLit (Chunks [] oldText)) ->-                        loop (TextLit (Chunks [] newText))-                      where-                        newText = Eval.textShow oldText-                    _ -> 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'  = shift   1  (V f 0) r-        b'  = subst (V f 0) r' b-        b'' = 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)-    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)] ""))-    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-    OptionalFold -> pure OptionalFold-    OptionalBuild -> pure OptionalBuild-    Record kts -> Record . Dhall.Map.sort <$> kts'-      where-        kts' = traverse loop kts-    RecordLit kvs -> RecordLit . Dhall.Map.sort <$> kvs'-      where-        kvs' = traverse loop kvs-    Union kts -> Union . Dhall.Map.sort <$> kts'-      where-        kts' = traverse (traverse loop) kts-    Combine 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 decide m n)-        decide l r =-            Combine 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 decide m n)-        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 l r-    RecordCompletion x y -> do-        loop (Annot (Prefer (Field x "default") y) (Field x "Type"))-    Merge x y t      -> do-        x' <- loop x-        y' <- loop y-        case x' of-            RecordLit kvsX ->-                case y' of-                    Field (Union ktsY) kY ->-                        case Dhall.Map.lookup kY ktsY of-                            Just Nothing ->-                                case Dhall.Map.lookup kY kvsX of-                                    Just vX -> return vX-                                    Nothing -> Merge x' y' <$> t'-                            _ ->-                                Merge x' y' <$> t'-                    App (Field (Union ktsY) kY) vY ->-                        case Dhall.Map.lookup kY ktsY of-                            Just (Just _) ->-                                case Dhall.Map.lookup kY kvsX of-                                    Just vX -> loop (App vX vY)-                                    Nothing -> Merge x' y' <$> t'-                            _ ->-                                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"  , TextLit (Chunks [] key))-                                , ("mapValue", value                  )-                                ]-                            )--                let keyValues = Data.Sequence.fromList (map entry (Dhall.Map.toList kvsX))--                let listType = case t' of-                        Just _ | null keyValues ->-                            t'-                        _ ->-                            Nothing--                return (ListLit listType keyValues)-            _ -> do-                return (ToMap x' t')-    Field r 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 v-                    Nothing -> Field <$> (RecordLit <$> traverse loop kvs) <*> pure x-            Project r_ _ -> loop (Field r_ x)-            Prefer (RecordLit kvs) r_ -> case Dhall.Map.lookup x kvs of-                Just v -> pure (Field (Prefer (singletonRecordLit v) r_) x)-                Nothing -> loop (Field r_ x)-            Prefer l (RecordLit kvs) -> case Dhall.Map.lookup x kvs of-                Just v -> pure v-                Nothing -> loop (Field l x)-            Combine (RecordLit kvs) r_ -> case Dhall.Map.lookup x kvs of-                Just v -> pure (Field (Combine (singletonRecordLit v) r_) x)-                Nothing -> loop (Field r_ x)-            Combine l (RecordLit kvs) -> case Dhall.Map.lookup x kvs of-                Just v -> pure (Field (Combine l (singletonRecordLit v)) x)-                Nothing -> loop (Field l x)-            _ -> pure (Field r' x)-    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 l' r')-            _ | null fields -> pure (RecordLit mempty)-              | otherwise   -> pure (Project x' (Left (Dhall.Set.sort fields)))-    Project r (Right e1) -> do-        e2 <- loop e1--        case e2 of-            Record kts -> do-                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--        pure (Assert t')-    Equivalent l r -> do-        l' <- loop l-        r' <- loop r--        pure (Equivalent l' r')-    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.-type NormalizerM m a = forall s. Expr s a -> m (Maybe (Expr s a))---- | An variation on `NormalizerM` for pure normalizers-type Normalizer a = NormalizerM Identity a---- | A reified 'Normalizer', which can be stored in structures without--- running into impredicative polymorphism.-newtype ReifiedNormalizer a = ReifiedNormalizer-  { getReifiedNormalizer :: Normalizer a }---- | Check if an expression is in a normal form given a context of evaluation.---   Unlike `isNormalized`, this will fully normalize and traverse through the expression.------   It is much more efficient to use `isNormalized`.------  `isNormalizedWith` can fail with an `error` if you check an ill-typed---  expression-isNormalizedWith :: (Eq s, Eq a) => Normalizer a -> Expr s a -> Bool-isNormalizedWith ctx e = e == normalizeWith (Just (ReifiedNormalizer ctx)) e---- | Quickly check if an expression is in normal form------ Given a well-typed expression @e@, @'isNormalized' e@ is equivalent to--- @e == 'normalize' e@.------ Given an ill-typed expression, 'isNormalized' may fail with an error, or--- evaluate to either False or True!-isNormalized :: Eq a => Expr s a -> Bool-isNormalized e0 = loop (denote e0)-  where-    loop e = case e of-      Const _ -> True-      Var _ -> True-      Lam _ a b -> loop a && loop b-      Pi _ a b -> loop a && loop b-      App f a -> loop f && loop a && case App f a of-          App (Lam _ _ _) _ -> False--          -- build/fold fusion for `List`-          App (App ListBuild _) (App (App ListFold _) _) -> False--          -- build/fold fusion for `Natural`-          App NaturalBuild (App NaturalFold _) -> False--          -- build/fold fusion for `Optional`-          App (App OptionalBuild _) (App (App OptionalFold _) _) -> False--          App (App (App (App NaturalFold (NaturalLit _)) _) _) _ -> False-          App NaturalFold (NaturalLit _) -> False-          App NaturalBuild _ -> False-          App NaturalIsZero (NaturalLit _) -> False-          App NaturalEven (NaturalLit _) -> False-          App NaturalOdd (NaturalLit _) -> False-          App NaturalShow (NaturalLit _) -> False-          App (App NaturalSubtract (NaturalLit _)) (NaturalLit _) -> False-          App (App NaturalSubtract (NaturalLit 0)) _ -> False-          App (App NaturalSubtract _) (NaturalLit 0) -> False-          App (App NaturalSubtract x) y -> not (Eval.judgmentallyEqual x y)-          App NaturalToInteger (NaturalLit _) -> False-          App IntegerShow (IntegerLit _) -> False-          App IntegerToDouble (IntegerLit _) -> False-          App DoubleShow (DoubleLit _) -> False-          App (App OptionalBuild _) _ -> False-          App (App ListBuild _) _ -> False-          App (App ListFold _) (ListLit _ _) -> False-          App (App ListLength _) (ListLit _ _) -> False-          App (App ListHead _) (ListLit _ _) -> False-          App (App ListLast _) (ListLit _ _) -> False-          App (App ListIndexed _) (ListLit _ _) -> False-          App (App ListReverse _) (ListLit _ _) -> False-          App (App OptionalFold _) (Some _) -> False-          App (App OptionalFold _) (App None _) -> False-          App TextShow (TextLit (Chunks [] _)) ->-              False-          _ -> True-      Let _ _ -> False-      Annot _ _ -> False-      Bool -> True-      BoolLit _ -> True-      BoolAnd x y -> loop x && loop y && decide x y-        where-          decide (BoolLit _)  _          = False-          decide  _          (BoolLit _) = False-          decide  l           r          = not (Eval.judgmentallyEqual l r)-      BoolOr x y -> loop x && loop y && decide x y-        where-          decide (BoolLit _)  _          = False-          decide  _          (BoolLit _) = False-          decide  l           r          = not (Eval.judgmentallyEqual l r)-      BoolEQ x y -> loop x && loop y && decide x y-        where-          decide (BoolLit True)  _             = False-          decide  _             (BoolLit True) = False-          decide  l              r             = not (Eval.judgmentallyEqual l r)-      BoolNE x y -> loop x && loop y && decide x y-        where-          decide (BoolLit False)  _               = False-          decide  _              (BoolLit False ) = False-          decide  l               r               = not (Eval.judgmentallyEqual l r)-      BoolIf x y z ->-          loop x && loop y && loop z && decide x y z-        where-          decide (BoolLit _)  _              _              = False-          decide  _          (BoolLit True) (BoolLit False) = False-          decide  _           l              r              = not (Eval.judgmentallyEqual l r)-      Natural -> True-      NaturalLit _ -> True-      NaturalFold -> True-      NaturalBuild -> True-      NaturalIsZero -> True-      NaturalEven -> True-      NaturalOdd -> True-      NaturalShow -> True-      NaturalSubtract -> True-      NaturalToInteger -> True-      NaturalPlus x y -> loop x && loop y && decide x y-        where-          decide (NaturalLit 0)  _             = False-          decide  _             (NaturalLit 0) = False-          decide (NaturalLit _) (NaturalLit _) = False-          decide  _              _             = True-      NaturalTimes x y -> loop x && loop y && decide x y-        where-          decide (NaturalLit 0)  _             = False-          decide  _             (NaturalLit 0) = False-          decide (NaturalLit 1)  _             = False-          decide  _             (NaturalLit 1) = False-          decide (NaturalLit _) (NaturalLit _) = False-          decide  _              _             = True-      Integer -> True-      IntegerLit _ -> True-      IntegerShow -> True-      IntegerToDouble -> True-      Double -> True-      DoubleLit _ -> True-      DoubleShow -> True-      Text -> True-      TextLit (Chunks [("", _)] "") -> False-      TextLit (Chunks xys _) -> all (all check) xys-        where-          check y = loop y && case y of-              TextLit _ -> False-              _         -> True-      TextAppend _ _ -> False-      TextShow -> True-      List -> True-      ListLit t es -> all loop t && all loop es-      ListAppend x y -> loop x && loop y && decide x y-        where-          decide (ListLit _ m)  _            | Data.Sequence.null m = False-          decide  _            (ListLit _ n) | Data.Sequence.null n = False-          decide (ListLit _ _) (ListLit _ _)                        = False-          decide  _             _                                   = True-      ListBuild -> True-      ListFold -> True-      ListLength -> True-      ListHead -> True-      ListLast -> True-      ListIndexed -> True-      ListReverse -> True-      Optional -> True-      Some a -> loop a-      None -> True-      OptionalFold -> True-      OptionalBuild -> True-      Record kts -> Dhall.Map.isSorted kts && all loop kts-      RecordLit kvs -> Dhall.Map.isSorted kvs && all loop kvs-      Union kts -> Dhall.Map.isSorted kts && all (all loop) kts-      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-        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-        where-          decide (RecordLit m) _ | Data.Foldable.null m = False-          decide _ (RecordLit n) | Data.Foldable.null n = False-          decide (RecordLit _) (RecordLit _) = False-          decide l r = not (Eval.judgmentallyEqual l r)-      RecordCompletion _ _ -> False-      Merge x y t -> loop x && loop y && all loop t-      ToMap x t -> case x of-          RecordLit _ -> False-          _ -> loop x && all loop t-      Field r k -> 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-          _ -> loop r-      Project r p -> loop r &&-          case p of-              Left s -> case r of-                  RecordLit _ -> False-                  Project _ _ -> False-                  Prefer _ (RecordLit _) -> False-                  _ -> not (Dhall.Set.null s) && Dhall.Set.isSorted s-              Right e' -> case e' of-                  Record _ -> False-                  _ -> loop e'-      Assert t -> loop t-      Equivalent l r -> loop l && loop r-      Note _ e' -> loop e'-      ImportAlt _ _ -> False-      Embed _ -> True--{-| Detect if the given variable is free within the given expression-->>> "x" `freeIn` "x"-True->>> "x" `freeIn` "y"-False->>> "x" `freeIn` Lam "x" (Const Type) "x"-False--}-freeIn :: Eq a => Var -> Expr s a -> Bool-variable@(V var i) `freeIn` expression =-    Dhall.Core.subst variable (Var (V var (i + 1))) strippedExpression-      /= strippedExpression-  where-    denote' :: Expr t b -> Expr () b-    denote' = denote--    strippedExpression = denote' expression+{-# LANGUAGE RankNTypes         #-}+{-# LANGUAGE RecordWildCards    #-}++{-| This module contains the core calculus for the Dhall language.++    Dhall is essentially a fork of the @morte@ compiler but with more built-in+    functionality, better error messages, and Haskell integration+-}++module Dhall.Core (+    -- * Syntax+      Const(..)+    , Directory(..)+    , File(..)+    , FilePrefix(..)+    , Import(..)+    , ImportHashed(..)+    , ImportMode(..)+    , ImportType(..)+    , URL(..)+    , Scheme(..)+    , DhallDouble(..)+    , Var(..)+    , Binding(..)+    , makeBinding+    , Chunks(..)+    , Expr(..)++    -- * Normalization+    , alphaNormalize+    , normalize+    , normalizeWith+    , normalizeWithM+    , Normalizer+    , NormalizerM+    , ReifiedNormalizer (..)+    , judgmentallyEqual+    , subst+    , shift+    , isNormalized+    , isNormalizedWith+    , denote+    , renote+    , shallowDenote+    , freeIn++    -- * Pretty-printing+    , pretty++    -- * Optics+    , subExpressions+    , chunkExprs+    , bindingExprs++    -- * Let-blocks+    , multiLet+    , wrapInLets+    , MultiLet(..)++    -- * Miscellaneous+    , internalError+    , reservedIdentifiers+    , escapeText+    , pathCharacter+    , throws+    , Eval.textShow+    , censorExpression+    , censorText+    ) where++import Control.Exception (Exception)+import Control.Monad.IO.Class (MonadIO(..))+import Data.Semigroup (Semigroup(..))+import Data.Text (Text)+import Data.Text.Prettyprint.Doc (Pretty)+import Dhall.Normalize+import Dhall.Src (Src(..))+import Dhall.Syntax+import Dhall.Pretty.Internal+import Instances.TH.Lift ()+import Lens.Family (over)+import Prelude hiding (succ)++import qualified Control.Exception+import qualified Dhall.Eval    as Eval+import qualified Data.Text  -- | Pretty-print a value pretty :: Pretty a => a -> Text
src/Dhall/Diff.hs view
@@ -25,8 +25,7 @@ import Data.Text (Text) import Data.Text.Prettyprint.Doc (Doc, Pretty) import Data.Void (Void)-import Dhall.Core (Binding(..), Chunks (..), Const(..), DhallDouble(..), Expr(..), Var(..))-import Dhall.Binary (ToTerm)+import Dhall.Syntax (Binding(..), Chunks (..), Const(..), DhallDouble(..), Expr(..), Var(..)) import Dhall.Map (Map) import Dhall.Set (Set) import Dhall.Pretty.Internal (Ann)@@ -37,7 +36,7 @@ import qualified Data.Set import qualified Data.Text import qualified Data.Text.Prettyprint.Doc  as Pretty-import qualified Dhall.Core+import qualified Dhall.Normalize import qualified Dhall.Map import qualified Dhall.Set import qualified Dhall.Pretty.Internal      as Internal@@ -156,11 +155,11 @@ rparen = token Internal.rparen  -- | Render the difference between the normal form of two expressions-diffNormalized :: (Eq a, Pretty a, ToTerm a) => Expr s a -> Expr s a -> Diff+diffNormalized :: (Eq a, Pretty a) => Expr s a -> Expr s a -> Diff diffNormalized l0 r0 = Dhall.Diff.diff l1 r1   where-    l1 = Dhall.Core.alphaNormalize (Dhall.Core.normalize l0)-    r1 = Dhall.Core.alphaNormalize (Dhall.Core.normalize r0)+    l1 = Dhall.Normalize.alphaNormalize (Dhall.Normalize.normalize l0)+    r1 = Dhall.Normalize.alphaNormalize (Dhall.Normalize.normalize r0)  diffPrimitive :: Eq a => (a -> Diff) -> a -> a -> Diff diffPrimitive f l r@@ -362,15 +361,23 @@ diffList     :: (Eq a, Pretty a)     => Seq (Expr Void a) -> Seq (Expr Void a) -> Diff-diffList l r = bracketed (foldMap diffPart parts)+diffList l r = bracketed (loop parts₀)   where     -- Sections of the list that are only in left, only in right, or in both-    parts =-        Algo.Diff.getGroupedDiffBy ((same .) . diff) (toList l) (toList r)+    parts₀ = Algo.Diff.getGroupedDiffBy equal (toList l) (toList r) +    equal a b = same (diff a b)+     -- Render each element of a list using an extra rendering function f     prettyElems f = map (f . token . Internal.prettyExpr) +    loop [] =+        mempty+    loop (Algo.Diff.First as : Algo.Diff.Second bs : parts)+        | length as == length bs = zipWith diff as bs <> loop parts+    loop (part : parts) =+        diffPart part <> loop parts+     diffPart part =       case part of         -- Only present in left@@ -1136,6 +1143,18 @@ diffPrimitiveExpression l@Integer r =     mismatch l r diffPrimitiveExpression l r@Integer =+    mismatch l r+diffPrimitiveExpression IntegerClamp IntegerClamp =+    "…"+diffPrimitiveExpression l@IntegerClamp r =+    mismatch l r+diffPrimitiveExpression l r@IntegerClamp =+    mismatch l r+diffPrimitiveExpression IntegerNegate IntegerNegate =+    "…"+diffPrimitiveExpression l@IntegerNegate r =+    mismatch l r+diffPrimitiveExpression l r@IntegerNegate =     mismatch l r diffPrimitiveExpression IntegerShow IntegerShow =     "…"
src/Dhall/Eval.hs view
@@ -133,15 +133,6 @@   -- ^ Don't store any information   | Typed !Text (Val a)   -- ^ Store the original name and type of the variable bound by the `Lam`-  | NaturalFoldCl (Val a)-  -- ^ The original function was a @Natural/fold@.  We need to preserve this-  --   information in order to implement @Natural/{build,fold}@ fusion-  | ListFoldCl (Val a)-  -- ^ The original function was a @List/fold@.  We need to preserve this-  --   information in order to implement @List/{build,fold}@ fusion-  | OptionalFoldCl (Val a)-  -- ^ The original function was an @Optional/fold@.  We need to preserve this-  --   information in order to implement @Optional/{build,fold}@ fusion   | NaturalSubtractZero   -- ^ The original function was a @Natural/subtract 0@.  We need to preserve   --   this information in case the @Natural/subtract@ ends up not being fully@@ -192,6 +183,8 @@      | VInteger     | VIntegerLit !Integer+    | VIntegerClamp !(Val a)+    | VIntegerNegate !(Val a)     | VIntegerShow !(Val a)     | VIntegerToDouble !(Val a) @@ -468,14 +461,12 @@                         go  acc m = go (vApp succ acc) (m - 1)                     in  go zero (fromIntegral n :: Integer)                 n ->-                    VHLam (NaturalFoldCl n) $ \natural ->+                    VPrim $ \natural ->                     VPrim $ \succ ->                     VPrim $ \zero ->                     VNaturalFold n natural succ zero         NaturalBuild ->             VPrim $ \case-                VHLam (NaturalFoldCl x) _ ->-                    x                 VPrimVar ->                     VNaturalBuild VPrimVar                 t ->       t@@ -526,6 +517,16 @@             VInteger         IntegerLit n ->             VIntegerLit n+        IntegerClamp ->+            VPrim $ \case+                VIntegerLit n+                    | 0 <= n    -> VNaturalLit (fromInteger n)+                    | otherwise -> VNaturalLit 0+                n -> VIntegerClamp n+        IntegerNegate ->+            VPrim $ \case+                VIntegerLit n -> VIntegerLit (negate n)+                n             -> VIntegerNegate n         IntegerShow ->             VPrim $ \case                 VIntegerLit n@@ -568,8 +569,6 @@         ListBuild ->             VPrim $ \a ->             VPrim $ \case-                VHLam (ListFoldCl x) _ ->-                    x                 VPrimVar ->                     VListBuild a VPrimVar                 t ->       t@@ -588,7 +587,7 @@                     VHLam (Typed "nil"  list) $ \nil ->                     foldr' (\x b -> cons `vApp` x `vApp` b) nil as                 as ->-                    VHLam (ListFoldCl as) $ \t ->+                    VPrim $ \t ->                     VPrim $ \c ->                     VPrim $ \n ->                     VListFold a as t c n@@ -620,14 +619,14 @@                 VListLit _ as ->                     let a' =                             if null as-                            then Just (VList (VRecord (Map.fromList [("index", VNatural), ("value", a)])))+                            then Just (VList (VRecord (Map.unorderedFromList [("index", VNatural), ("value", a)])))                             else Nothing                          as' =                             Sequence.mapWithIndex                                 (\i t ->                                     VRecordLit-                                        (Map.fromList+                                        (Map.unorderedFromList                                             [ ("index", VNaturalLit (fromIntegral i))                                             , ("value", t)                                             ]@@ -667,14 +666,13 @@                     VHLam (Typed "none" optional) $ \_none ->                     some `vApp` t                 opt ->-                    VHLam (OptionalFoldCl opt) $ \o ->+                    VPrim $ \o ->                     VPrim $ \s ->                     VPrim $ \n ->                     VOptionalFold a opt o s n         OptionalBuild ->             VPrim $ \ ~a ->             VPrim $ \case-                VHLam (OptionalFoldCl x) _ -> x                 VPrimVar -> VOptionalBuild a VPrimVar                 t ->       t                     `vApp` VOptional a@@ -703,17 +701,17 @@         ToMap x ma ->             case (eval env x, fmap (eval env) ma) of                 (VRecordLit m, ma'@(Just _)) | null m ->-                    VListLit ma' (Sequence.empty)+                    VListLit ma' Sequence.empty                 (VRecordLit m, _) ->                     let entry (k, v) =                             VRecordLit-                                (Map.fromList+                                (Map.unorderedFromList                                     [ ("mapKey", VTextLit $ VChunks [] k)                                     , ("mapValue", v)                                     ]                                 ) -                        s = (Sequence.fromList . map entry . Map.toList) m+                        s = (Sequence.fromList . map entry . Map.toAscList) m                      in  VListLit Nothing s                 (x', ma') ->@@ -761,7 +759,7 @@ eqMapsBy :: Ord k => (v -> v -> Bool) -> Map k v -> Map k v -> Bool eqMapsBy f mL mR =     Map.size mL == Map.size mR-    && eqListBy eq (Map.toList mL) (Map.toList mR)+    && eqListBy eq (Map.toAscList mL) (Map.toAscList mR)   where     eq (kL, vL) (kR, vR) = kL == kR && f vL vR {-# INLINE eqMapsBy #-}@@ -864,6 +862,10 @@             True         (VIntegerLit t, VIntegerLit t') ->             t == t'+        (VIntegerClamp t, VIntegerClamp t') ->+            conv env t t'+        (VIntegerNegate t, VIntegerNegate t') ->+            conv env t t'         (VIntegerShow t, VIntegerShow t') ->             conv env t t'         (VIntegerToDouble t, VIntegerToDouble t') ->@@ -998,9 +1000,6 @@             case i of                 Typed (fresh -> (x, v)) a -> Lam x (quote env a) (quoteBind x (t v))                 Prim                      -> quote env (t VPrimVar)-                NaturalFoldCl{}           -> quote env (t VPrimVar)-                ListFoldCl{}              -> quote env (t VPrimVar)-                OptionalFoldCl{}          -> quote env (t VPrimVar)                 NaturalSubtractZero       -> App NaturalSubtract (NaturalLit 0)          VPi a (freshClosure -> (x, v, b)) ->@@ -1049,6 +1048,10 @@             Integer         VIntegerLit n ->             IntegerLit n+        VIntegerClamp t ->+            IntegerClamp `qApp` t+        VIntegerNegate t ->+            IntegerNegate `qApp` t         VIntegerShow t ->             IntegerShow `qApp` t         VIntegerToDouble t ->@@ -1225,6 +1228,10 @@                 Integer             IntegerLit n ->                 IntegerLit n+            IntegerClamp ->+                IntegerClamp+            IntegerNegate ->+                IntegerNegate             IntegerShow ->                 IntegerShow             IntegerToDouble ->
src/Dhall/Format.hs view
@@ -13,8 +13,8 @@  import Control.Exception (Exception) import Data.Monoid ((<>))-import Dhall.Pretty (CharacterSet(..), annToAnsiStyle, layoutOpts)-import Dhall.Util (Censor, Input(..))+import Dhall.Pretty (CharacterSet(..), annToAnsiStyle)+import Dhall.Util (Censor, Input(..), Header(..))  import qualified Data.Text.Prettyprint.Doc                 as Pretty import qualified Data.Text.Prettyprint.Doc.Render.Terminal as Pretty.Terminal@@ -23,6 +23,7 @@ import qualified Data.Text.IO import qualified Dhall.Pretty import qualified Dhall.Util+import qualified System.AtomicWrite.Writer.LazyText        as AtomicWrite.LazyText import qualified System.Console.ANSI import qualified System.IO @@ -50,50 +51,49 @@ format     :: Format     -> IO ()-format (Format {..}) =+format (Format {..}) = do+    let layoutHeaderAndExpr (Header header, expr) =+            Dhall.Pretty.layout+                (   Pretty.pretty header+                <>  Dhall.Pretty.prettyCharacterSet characterSet expr +                <>  "\n")++    let layoutInput input = do+            headerAndExpr <- Dhall.Util.getExpressionAndHeader censor input++            return (layoutHeaderAndExpr headerAndExpr)+     case formatMode of-        Modify {..} ->+        Modify {..} -> do+            docStream <- layoutInput inplace+             case inplace of                 InputFile file -> do-                    (header, expr) <- Dhall.Util.getExpressionAndHeader censor (InputFile file)--                    let doc =   Pretty.pretty header-                            <>  Pretty.unAnnotate (Dhall.Pretty.prettyCharacterSet characterSet expr)-                            <>  "\n"+                    AtomicWrite.LazyText.atomicWriteFile+                        file+                        (Pretty.Text.renderLazy docStream) -                    System.IO.withFile file System.IO.WriteMode (\handle -> do-                        Pretty.Terminal.renderIO handle (Pretty.layoutSmart layoutOpts doc))                 StandardInput -> do-                    (header, expr) <- Dhall.Util.getExpressionAndHeader censor StandardInput--                    let doc =   Pretty.pretty header-                            <>  Dhall.Pretty.prettyCharacterSet characterSet expr-                            <>  "\n"-                     supportsANSI <- System.Console.ANSI.hSupportsANSI System.IO.stdout -                    if supportsANSI-                      then-                        Pretty.Terminal.renderIO-                          System.IO.stdout-                          (fmap annToAnsiStyle (Pretty.layoutSmart layoutOpts doc))-                      else-                        Pretty.Terminal.renderIO-                          System.IO.stdout-                          (Pretty.layoutSmart layoutOpts (Pretty.unAnnotate doc))+                    Pretty.Terminal.renderIO+                        System.IO.stdout+                        (if supportsANSI+                            then (fmap annToAnsiStyle docStream)+                            else (Pretty.unAnnotateS docStream))+         Check {..} -> do             originalText <- case path of                 InputFile file -> Data.Text.IO.readFile file                 StandardInput  -> Data.Text.IO.getContents -            (header, expr) <- Dhall.Util.getExpressionAndHeader censor path--            let doc =   Pretty.pretty header-                    <>  Pretty.unAnnotate (Dhall.Pretty.prettyCharacterSet characterSet expr)-                    <>  "\n"+            docStream <- case path of+                InputFile _    -> layoutInput path+                StandardInput  -> do+                    headerAndExpr <- Dhall.Util.getExpressionAndHeaderFromStdinText censor originalText+                    return (layoutHeaderAndExpr headerAndExpr) -            let formattedText =-                    Pretty.Text.renderStrict (Pretty.layoutSmart layoutOpts doc)+            let formattedText = Pretty.Text.renderStrict docStream              if originalText == formattedText                 then return ()
src/Dhall/Freeze.hs view
@@ -14,13 +14,11 @@     , Intent(..)     ) where -import Control.Exception (SomeException) import Data.Monoid ((<>)) import Data.Text-import Data.Void (Void)-import Dhall.Core (Expr(..), Import(..), ImportHashed(..), ImportType(..)) import Dhall.Parser (Src)-import Dhall.Pretty (CharacterSet, annToAnsiStyle, layoutOpts, prettyCharacterSet)+import Dhall.Pretty (CharacterSet)+import Dhall.Syntax (Expr(..), Import(..), ImportHashed(..), ImportType(..)) import Dhall.Util (Censor, Input(..)) import System.Console.ANSI (hSupportsANSI) @@ -28,12 +26,14 @@ import qualified Control.Monad.Trans.State.Strict          as State import qualified Data.Text.Prettyprint.Doc                 as Pretty import qualified Data.Text.Prettyprint.Doc.Render.Terminal as Pretty-import qualified Data.Text.IO+import qualified Data.Text.Prettyprint.Doc.Render.Text     as Pretty.Text import qualified Dhall.Core import qualified Dhall.Import import qualified Dhall.Optics+import qualified Dhall.Pretty import qualified Dhall.TypeCheck import qualified Dhall.Util+import qualified System.AtomicWrite.Writer.LazyText        as AtomicWrite.LazyText import qualified System.FilePath import qualified System.IO @@ -54,15 +54,7 @@      let status = Dhall.Import.emptyStatus directory -    let download =-            State.evalStateT (Dhall.Import.loadWith (Embed import_)) status--    -- Try again without the semantic integrity check if decoding fails-    let handler :: SomeException -> IO (Expr Src Void)-        handler _ = do-            State.evalStateT (Dhall.Import.loadWith (Embed unprotectedImport)) status--    expression <- Control.Exception.handle handler download+    expression <- State.evalStateT (Dhall.Import.loadWith (Embed unprotectedImport)) status      case Dhall.TypeCheck.typeOf expression of         Left  exception -> Control.Exception.throwIO exception@@ -72,7 +64,7 @@             Dhall.Core.alphaNormalize (Dhall.Core.normalize expression)      -- make sure the frozen import is present in the semantic cache-    Dhall.Import.writeExpressionToSemanticCache expression+    Dhall.Import.writeExpressionToSemanticCache (Dhall.Core.denote expression)      let expressionHash = Dhall.Import.hashExpression normalizedExpression @@ -97,20 +89,23 @@ writeExpr inplace (header, expr) characterSet = do     let doc =  Pretty.pretty header             <> Dhall.Pretty.prettyCharacterSet characterSet expr+            <> "\n" -    let unAnnotated = Pretty.layoutSmart layoutOpts (Pretty.unAnnotate doc)+    let stream = Dhall.Pretty.layout doc +    let unAnnotated = Pretty.unAnnotateS stream+     case inplace of-        InputFile f ->-            System.IO.withFile f System.IO.WriteMode (\handle -> do-                Pretty.renderIO handle unAnnotated-                Data.Text.IO.hPutStrLn handle "" )+        InputFile file ->+            AtomicWrite.LazyText.atomicWriteFile+                file+                (Pretty.Text.renderLazy unAnnotated)          StandardInput -> do             supportsANSI <- System.Console.ANSI.hSupportsANSI System.IO.stdout             if supportsANSI                then-                 Pretty.renderIO System.IO.stdout (annToAnsiStyle <$> Pretty.layoutSmart layoutOpts doc)+                 Pretty.renderIO System.IO.stdout (Dhall.Pretty.annToAnsiStyle <$> stream)                else                  Pretty.renderIO System.IO.stdout unAnnotated @@ -145,7 +140,8 @@             StandardInput  -> "."             InputFile file -> System.FilePath.takeDirectory file -    (header, parsedExpression) <- Dhall.Util.getExpressionAndHeader censor inplace+    (Dhall.Util.Header header, parsedExpression) <-+        Dhall.Util.getExpressionAndHeader censor inplace      let freezeScope =             case scope of
src/Dhall/Import.hs view
@@ -138,7 +138,6 @@     ) where  import Control.Applicative (Alternative(..))-import Codec.CBOR.Term (Term(..)) import Control.Exception (Exception, SomeException, IOException, toException) import Control.Monad (when) import Control.Monad.Catch (throwM, MonadCatch(catch), handle)@@ -158,7 +157,7 @@ import Data.Typeable (Typeable) import System.FilePath ((</>)) import Dhall.Binary (StandardVersion(..))-import Dhall.Core+import Dhall.Syntax     ( Expr(..)     , Chunks(..)     , Directory(..)@@ -173,24 +172,25 @@     , chunkExprs     ) #ifdef WITH_HTTP-import Dhall.Import.HTTP hiding (HTTPHeader)+import Dhall.Import.HTTP #endif import Dhall.Import.Types  import Dhall.Parser (Parser(..), ParseError(..), Src(..), SourcedException(..)) import Lens.Family.State.Strict (zoom) +import qualified Codec.CBOR.Encoding                         as Encoding+import qualified Codec.CBOR.Write                            as Write import qualified Codec.Serialise-import qualified Control.Monad.Trans.Maybe        as Maybe-import qualified Control.Monad.Trans.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.Map.Strict                  as Map+import qualified Data.List.NonEmpty                          as NonEmpty import qualified Data.Text.Encoding-import qualified Data.Text                        as Text+import qualified Data.Text                                   as Text import qualified Data.Text.IO import qualified Dhall.Binary import qualified Dhall.Core@@ -199,11 +199,12 @@ import qualified Dhall.Parser import qualified Dhall.Pretty.Internal import qualified Dhall.TypeCheck+import qualified System.AtomicWrite.Writer.ByteString.Binary as AtomicWrite.Binary import qualified System.Environment import qualified System.Info import qualified System.IO-import qualified System.Directory                 as Directory-import qualified System.FilePath                  as FilePath+import qualified System.Directory                            as Directory+import qualified System.FilePath                             as FilePath import qualified Text.Megaparsec import qualified Text.Parser.Combinators import qualified Text.Parser.Token@@ -478,11 +479,12 @@ loadImport :: Chained -> StateT Status IO ImportSemantics loadImport import_ = do     Status {..} <- State.get-    case Map.lookup import_ _cache of++    case Dhall.Map.lookup import_ _cache of         Just importSemantics -> return importSemantics         Nothing -> do             importSemantics <- loadImportWithSemanticCache import_-            zoom cache (State.modify (Map.insert import_ importSemantics))+            zoom cache (State.modify (Dhall.Map.insert import_ importSemantics))             return importSemantics  -- | Load an import from the 'semantic cache'. Defers to@@ -504,6 +506,7 @@     case mCached of         Just bytesStrict -> do             let actualHash = Dhall.Crypto.sha256Hash bytesStrict+             if semanticHash == actualHash                 then return ()                 else do@@ -511,13 +514,11 @@                     throwMissingImport (Imported _stack (HashMismatch {expectedHash = semanticHash, ..}))              let bytesLazy = Data.ByteString.Lazy.fromStrict bytesStrict-            term <- case Codec.Serialise.deserialiseOrFail bytesLazy of-                Left err -> throwMissingImport (Imported _stack err)-                Right t -> return t-            importSemantics <- case Dhall.Binary.decodeExpression term of-                Left err -> throwMissingImport (Imported _stack err)-                Right sem -> return sem +            importSemantics <- case Dhall.Binary.decodeExpression bytesLazy of+                Left  err -> throwMissingImport (Imported _stack err)+                Right e   -> return e+             return (ImportSemantics {..})          Nothing -> do@@ -544,7 +545,7 @@  -- | Ensure that the given expression is present in the semantic cache. The --   given expression should be alpha-beta-normal.-writeExpressionToSemanticCache :: Expr Src Void -> IO ()+writeExpressionToSemanticCache :: Expr Void Void -> IO () writeExpressionToSemanticCache expression = writeToSemanticCache hash bytes   where     bytes = encodeExpression NoVersion expression@@ -554,7 +555,7 @@ writeToSemanticCache hash bytes = do     _ <- Maybe.runMaybeT $ do         cacheFile <- getCacheFile "dhall" hash-        liftIO (Data.ByteString.writeFile cacheFile bytes)+        liftIO (AtomicWrite.Binary.atomicWriteFile cacheFile bytes)     return ()  -- Check the "semi-semantic" disk cache, otherwise typecheck and normalise from@@ -592,18 +593,14 @@     -- Check the semi-semantic cache. See     -- https://github.com/dhall-lang/dhall-haskell/issues/1098 for the reasoning     -- behind semi-semantic caching.-    let semisemanticHash = computeSemisemanticHash resolvedExpr+    let semisemanticHash = computeSemisemanticHash (Dhall.Core.denote resolvedExpr)     mCached <- lift $ fetchFromSemisemanticCache semisemanticHash      importSemantics <- case mCached of         Just bytesStrict -> do             let bytesLazy = Data.ByteString.Lazy.fromStrict bytesStrict -            term <- case Codec.Serialise.deserialiseOrFail bytesLazy of-                Left err -> throwMissingImport (Imported _stack err)-                Right t -> return t--            importSemantics <- case Dhall.Binary.decodeExpression term of+            importSemantics <- case Dhall.Binary.decodeExpression bytesLazy of                 Left err -> throwMissingImport (Imported _stack err)                 Right sem -> return sem @@ -659,7 +656,7 @@ -- AST (without normalising or type-checking it first). See -- https://github.com/dhall-lang/dhall-haskell/issues/1098 for further -- discussion.-computeSemisemanticHash :: Expr Src Void -> Dhall.Crypto.SHA256Digest+computeSemisemanticHash :: Expr Void Void -> Dhall.Crypto.SHA256Digest computeSemisemanticHash resolvedExpr = hashExpression resolvedExpr  -- Fetch encoded normal form from "semi-semantic cache"@@ -673,7 +670,7 @@ writeToSemisemanticCache semisemanticHash bytes = do     _ <- Maybe.runMaybeT $ do         cacheFile <- getCacheFile "dhall-haskell" semisemanticHash-        liftIO (Data.ByteString.writeFile cacheFile bytes)+        liftIO (AtomicWrite.Binary.atomicWriteFile cacheFile bytes)     return ()  -- Fetch source code directly from disk/network@@ -988,7 +985,7 @@     let local (Chained (Import (ImportHashed _ (Remote  {})) _)) = False         local (Chained (Import (ImportHashed _ (Local   {})) _)) = True         local (Chained (Import (ImportHashed _ (Env     {})) _)) = True-        local (Chained (Import (ImportHashed _ (Missing {})) _)) = True+        local (Chained (Import (ImportHashed _ (Missing {})) _)) = False      let referentiallySane = not (local child) || local parent @@ -1012,7 +1009,7 @@     ImportSemantics {..} <- loadImport child     zoom stack (State.put _stack) -    return importSemantics+    return (Dhall.Core.renote importSemantics)    ImportAlt a b -> loadWith a `catch` handler₀     where@@ -1052,6 +1049,8 @@   NaturalTimes a b     -> NaturalTimes <$> loadWith a <*> loadWith b   Integer              -> pure Integer   IntegerLit a         -> pure (IntegerLit a)+  IntegerClamp         -> pure IntegerClamp+  IntegerNegate        -> pure IntegerNegate   IntegerShow          -> pure IntegerShow   IntegerToDouble      -> pure IntegerToDouble   Double               -> pure Double@@ -1107,33 +1106,30 @@         (emptyStatus rootDirectory) { _semanticCacheMode = semanticCacheMode }  encodeExpression-    :: forall s-    .  StandardVersion+    :: StandardVersion     -- ^ `NoVersion` means to encode without the version tag-    -> Expr s Void+    -> Expr Void Void     -> Data.ByteString.ByteString encodeExpression _standardVersion expression = bytesStrict   where-    intermediateExpression :: Expr s Import+    intermediateExpression :: Expr Void Import     intermediateExpression = fmap absurd expression -    term :: Term-    term = Dhall.Binary.encodeExpression intermediateExpression--    taggedTerm :: Term-    taggedTerm =+    encoding =         case _standardVersion of-            NoVersion -> term-            s         -> TList [ TString v, term ]+            NoVersion ->+                Codec.Serialise.encode intermediateExpression+            s ->+                    Encoding.encodeListLen 2+                <>  Encoding.encodeString v+                <>  Codec.Serialise.encode intermediateExpression               where                 v = Dhall.Binary.renderStandardVersion s -    bytesLazy = Codec.Serialise.serialise taggedTerm--    bytesStrict = Data.ByteString.Lazy.toStrict bytesLazy+    bytesStrict = Write.toStrictByteString encoding  -- | Hash a fully resolved expression-hashExpression :: Expr s Void -> Dhall.Crypto.SHA256Digest+hashExpression :: Expr Void Void -> Dhall.Crypto.SHA256Digest hashExpression expression =     Dhall.Crypto.sha256Hash (encodeExpression NoVersion expression) @@ -1143,7 +1139,7 @@     In other words, the output of this function can be pasted into Dhall     source code to add an integrity check to an import -}-hashExpressionToCode :: Expr s Void -> Text+hashExpressionToCode :: Expr Void Void -> Text hashExpressionToCode expr =     "sha256:" <> Text.pack (show (hashExpression expr)) 
src/Dhall/Import/Types.hs view
@@ -1,5 +1,7 @@+{-# LANGUAGE CPP               #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards   #-}+ {-# OPTIONS_GHC -Wall #-}  module Dhall.Import.Types where@@ -8,7 +10,7 @@ import Control.Monad.Trans.State.Strict (StateT) import Data.Dynamic import Data.List.NonEmpty (NonEmpty)-import Data.Map (Map)+import Dhall.Map (Map) import Data.Semigroup ((<>)) import Data.Text.Prettyprint.Doc (Pretty(..)) import Data.Void (Void)@@ -25,12 +27,15 @@   , ReifiedNormalizer(..)   , URL   )+#ifdef WITH_HTTP+import Dhall.Import.Manager (Manager)+#endif import Dhall.Parser (Src) import Lens.Family (LensLike') import System.FilePath (isRelative, splitDirectories)  import qualified Dhall.Context-import qualified Data.Map      as Map+import qualified Dhall.Map     as Map import qualified Data.Text  -- | A fully 'chained' import, i.e. if it contains a relative path that path is@@ -49,7 +54,7 @@  -- | An import that has been fully interpeted data ImportSemantics = ImportSemantics-    { importSemantics :: Expr Src Void+    { importSemantics :: Expr Void Void     -- ^ The fully resolved import, typechecked and beta-normal.     } @@ -75,6 +80,13 @@     -- ^ Cache of imported expressions with their node id in order to avoid     --   importing the same expression twice with different values +#ifdef WITH_HTTP+    , _manager :: Maybe Manager+#else+    , _manager :: Maybe Void+#endif+    -- ^ Used to cache the `Manager` when making multiple requests+     , _remote :: URL -> StateT Status IO Data.Text.Text     -- ^ The remote resolver, fetches the content at the given URL. @@ -95,6 +107,8 @@     _graph = []      _cache = Map.empty++    _manager = Nothing      _normalizer = Nothing 
src/Dhall/Lint.hs view
@@ -1,4 +1,7 @@-{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE NamedFieldPuns    #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE PatternGuards     #-}+{-# LANGUAGE RecordWildCards   #-}  -- | This module contains the implementation of the @dhall lint@ command @@ -6,11 +9,26 @@     ( -- * Lint       lint     , removeUnusedBindings+    , fixAssert+    , fixParentPath     ) where  import Control.Applicative ((<|>))-import Dhall.Core (Binding(..), Expr(..), Import, Var(..), subExpressions) +import Dhall.Syntax+    ( Binding(..)+    , Directory(..)+    , Expr(..)+    , File(..)+    , FilePrefix(..)+    , Import(..)+    , ImportHashed(..)+    , ImportType(..)+    , Var(..)+    , subExpressions+    )++import qualified Data.List.NonEmpty as NonEmpty import qualified Dhall.Core import qualified Dhall.Optics import qualified Lens.Family@@ -22,12 +40,13 @@     * removes unused @let@ bindings with 'removeUnusedBindings'.     * fixes @let a = x ≡ y@ to be @let a = assert : x ≡ y@     * 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 t Import lint =       Dhall.Optics.rewriteOf         subExpressions-        (\e -> fixAsserts e <|> removeUnusedBindings e)+        (\e -> fixAssert e <|> removeUnusedBindings e <|> fixParentPath e)     . removeLetInLet  -- | Remove unused `Let` bindings.@@ -40,12 +59,41 @@         Just (Dhall.Core.shift (-1) (V a 0) d) removeUnusedBindings _ = Nothing --- Fix `Let` bindings  that the user probably meant to be `assert`s-fixAsserts :: Expr s a -> Maybe (Expr s a)-fixAsserts (Let (Binding { value = Equivalent x y, ..}) body) =+-- | Fix `Let` bindings  that the user probably meant to be `assert`s+fixAssert :: Expr s a -> Maybe (Expr s a)+fixAssert (Let (Binding { value = Equivalent x y, ..}) body) =     Just (Let (Binding { value = Assert (Equivalent x y), .. }) body)-fixAsserts _ =+fixAssert (Let binding (Equivalent x y)) =+    Just (Let binding (Assert (Equivalent x y)))+fixAssert _ =     Nothing++-- | This transforms @.\/..\/foo@ into @..\/foo@+fixParentPath :: Expr s Import -> Maybe (Expr s Import)+fixParentPath (Embed oldImport) = do+    let Import{..} = oldImport++    let ImportHashed{..} = importHashed++    case importType of+        Local Here File{ directory = Directory { components }, .. }+            | Just nonEmpty <- NonEmpty.nonEmpty components+            , NonEmpty.last nonEmpty == ".." -> do+                let newDirectory =+                        Directory { components = NonEmpty.init nonEmpty }++                let newImportType =+                        Local Parent File{ directory = newDirectory, .. }++                let newImportHashed =+                        ImportHashed { importType = newImportType, .. }++                let newImport = Import { importHashed = newImportHashed, .. }++                Just (Embed newImport)+        _ ->+            Nothing+fixParentPath _  = Nothing  isOrContainsAssert :: Expr s a -> Bool isOrContainsAssert (Assert _) = True
src/Dhall/Main.hs view
@@ -32,9 +32,9 @@ import Dhall.Freeze (Intent(..), Scope(..)) import Dhall.Import (Imported(..), Depends(..), SemanticCacheMode(..), _semanticCacheMode) import Dhall.Parser (Src)-import Dhall.Pretty (Ann, CharacterSet(..), annToAnsiStyle, layoutOpts)+import Dhall.Pretty (Ann, CharacterSet(..), annToAnsiStyle) import Dhall.TypeCheck (Censored(..), DetailedTypeError(..), TypeError)-import Dhall.Util (Censor(..), Input(..), Output(..))+import Dhall.Util (Censor(..), Header (..), Input(..), Output(..)) import Dhall.Version (dhallVersionString) import Options.Applicative (Parser, ParserInfo) import System.Exit (ExitCode, exitFailure)@@ -44,17 +44,18 @@ import qualified Codec.CBOR.JSON import qualified Codec.CBOR.Read import qualified Codec.CBOR.Write-import qualified Codec.Serialise import qualified Control.Exception import qualified Control.Monad.Trans.State.Strict          as State import qualified Data.Aeson import qualified Data.Aeson.Encode.Pretty import qualified Data.ByteString.Lazy import qualified Data.ByteString.Lazy.Char8+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@@ -64,6 +65,7 @@ import qualified Dhall.Import import qualified Dhall.Import.Types import qualified Dhall.Lint+import qualified Dhall.Map import qualified Dhall.Tags import qualified Dhall.Pretty import qualified Dhall.Repl@@ -71,12 +73,13 @@ import qualified Dhall.Util import qualified GHC.IO.Encoding import qualified Options.Applicative+import qualified System.AtomicWrite.Writer.LazyText        as AtomicWrite.LazyText import qualified System.Console.ANSI import qualified System.Exit                               as Exit import qualified System.IO import qualified System.FilePath import qualified Text.Dot-import qualified Data.Map+import qualified Text.Pretty.Simple  -- | Top-level program options data Options = Options@@ -130,6 +133,7 @@     | Encode { file :: Input, json :: Bool }     | Decode { file :: Input, json :: Bool }     | Text { file :: Input }+    | SyntaxTree { file :: Input }  data ResolveMode     = Dot@@ -158,11 +162,12 @@         f True  = Censor         f False = NoCensor -subcommand :: String -> String -> Parser a -> Parser a-subcommand name description parser =+subcommand' :: Bool -> String -> String -> Parser a -> Parser a+subcommand' internal name description parser =     Options.Applicative.hsubparser         (   Options.Applicative.command name parserInfo         <>  Options.Applicative.metavar name+        <>  if internal then Options.Applicative.internal else mempty         )   where     parserInfo =@@ -171,6 +176,12 @@             <>  Options.Applicative.progDesc description             ) +subcommand :: String -> String -> Parser a -> Parser a+subcommand = subcommand' False++internalSubcommand :: String -> String -> Parser a -> Parser a+internalSubcommand = subcommand' True+ parseMode :: Parser Mode parseMode =         subcommand@@ -229,6 +240,10 @@             "text"             "Render a Dhall expression that evaluates to a Text literal"             (Text <$> parseFile)+    <|> internalSubcommand+            "haskell-syntax-tree"+            "Output the parsed syntax tree (for debugging)"+            (SyntaxTree <$> parseFile)     <|> (   Default         <$> parseFile         <*> parseOutput@@ -308,7 +323,7 @@           Options.Applicative.flag' (Just ListTransitiveDependencies)               (   Options.Applicative.long "transitive-dependencies"               <>  Options.Applicative.help-                    "List transitive import dependencies"+                    "List transitive import dependencies in post-order"               )         <|> pure Nothing @@ -470,7 +485,7 @@      let renderDoc :: Handle -> Doc Ann -> IO ()         renderDoc h doc = do-            let stream = Pretty.layoutSmart layoutOpts doc+            let stream = Dhall.Pretty.layout doc              supportsANSI <- System.Console.ANSI.hSupportsANSI h             let ansiStream =@@ -487,6 +502,12 @@              renderDoc h doc +    let writeDocToFile :: FilePath -> Doc ann -> IO ()+        writeDocToFile file doc = do+            let stream = Dhall.Pretty.layout (doc <> "\n")++            AtomicWrite.LazyText.atomicWriteFile file (Pretty.Text.renderLazy stream)+     when (not $ ignoreSemanticCache mode) Dhall.Import.warnAboutMissingCaches      handle $ case mode of@@ -521,8 +542,11 @@              case output of                 StandardOutput -> render System.IO.stdout annotatedExpression+                 OutputFile file_ ->-                    System.IO.withFile file_ System.IO.WriteMode $ \h -> render h annotatedExpression+                    writeDocToFile+                        file_+                        (Dhall.Pretty.prettyCharacterSet characterSet annotatedExpression)          Resolve { resolveMode = Just Dot, ..} -> do             expression <- getExpression file@@ -571,7 +595,8 @@                           .   Dhall.Core.importType                           .   Dhall.Core.importHashed                           .   Dhall.Import.chainedImport )-                 .   Data.Map.keys+                 .   reverse+                 .   Dhall.Map.keys                  $   _cache          Resolve { resolveMode = Nothing, ..} -> do@@ -650,32 +675,22 @@             Data.Text.IO.putStrLn (Dhall.Import.hashExpressionToCode normalizedExpression)          Lint {..} -> do-            (header, expression) <- getExpressionAndHeader inplace--            case inplace of-                InputFile file -> do-                    let lintedExpression = Dhall.Lint.lint expression--                    let doc =   Pretty.pretty header-                            <>  Dhall.Pretty.prettyCharacterSet characterSet lintedExpression+            (Header header, expression) <- getExpressionAndHeader inplace -                    System.IO.withFile file System.IO.WriteMode (\h -> do-                        renderDoc h doc )+            let lintedExpression = Dhall.Lint.lint expression -                StandardInput -> do-                    let lintedExpression = Dhall.Lint.lint expression+            let doc =   Pretty.pretty header+                    <>  Dhall.Pretty.prettyCharacterSet characterSet lintedExpression -                    let doc =   Pretty.pretty header-                            <>  Dhall.Pretty.prettyCharacterSet characterSet lintedExpression+            case inplace of+                InputFile file -> writeDocToFile file doc -                    renderDoc System.IO.stdout doc+                StandardInput -> renderDoc System.IO.stdout doc          Encode {..} -> do             expression <- getExpression file -            let term = Dhall.Binary.encodeExpression expression--            let bytes = Codec.Serialise.serialise term+            let bytes = Dhall.Binary.encodeExpression (Dhall.Core.denote expression)              if json                 then do@@ -696,7 +711,7 @@                     InputFile f   -> Data.ByteString.Lazy.readFile f                     StandardInput -> Data.ByteString.Lazy.getContents -            term <- do+            expression <- do                 if json                     then do                         value <- case Data.Aeson.eitherDecode' bytes of@@ -705,15 +720,14 @@                          let encoding = Codec.CBOR.JSON.encodeValue value -                        let cborBytes = Codec.CBOR.Write.toLazyByteString encoding-                        Dhall.Core.throws (Codec.Serialise.deserialiseOrFail cborBytes)+                        let cborgBytes = Codec.CBOR.Write.toLazyByteString encoding++                        Dhall.Core.throws (Dhall.Binary.decodeExpression cborgBytes)                     else do-                        Dhall.Core.throws (Codec.Serialise.deserialiseOrFail bytes)+                        Dhall.Core.throws (Dhall.Binary.decodeExpression bytes) -            expression <- Dhall.Core.throws (Dhall.Binary.decodeExpression term)-                :: IO (Expr Src Import) -            let doc = Dhall.Pretty.prettyCharacterSet characterSet expression+            let doc = Dhall.Pretty.prettyCharacterSet characterSet (Dhall.Core.renote expression :: Expr Src Import)              renderDoc System.IO.stdout doc @@ -731,13 +745,13 @@                 Dhall.Core.TextLit (Dhall.Core.Chunks [] text) -> do                     Data.Text.IO.putStr text                 _ -> do-                    let invalidTypeExpected :: Expr Void Void-                        invalidTypeExpected = Dhall.Core.Text+                    let invalidDecoderExpected :: Expr Void Void+                        invalidDecoderExpected = Dhall.Core.Text -                    let invalidTypeExpression :: Expr Void Void-                        invalidTypeExpression = normalizedExpression+                    let invalidDecoderExpression :: Expr Void Void+                        invalidDecoderExpression = normalizedExpression -                    Control.Exception.throwIO (Dhall.InvalidType {..})+                    Control.Exception.throwIO (Dhall.InvalidDecoder {..})          Tags {..} -> do             tags <- Dhall.Tags.generate input suffixes followSymlinks@@ -747,7 +761,14 @@                     System.IO.withFile file System.IO.WriteMode (`Data.Text.IO.hPutStr` tags)                  StandardOutput -> Data.Text.IO.putStrLn tags-            ++        SyntaxTree {..} -> do+            expression <- getExpression file++            let denoted :: Expr Void Import+                denoted = Dhall.Core.denote expression++            Text.Pretty.Simple.pPrintNoColor denoted  -- | Entry point for the @dhall@ executable main :: IO ()
src/Dhall/Map.hs view
@@ -13,6 +13,7 @@       Map        -- * Construction+    , empty     , singleton     , fromList     , fromListWithKey@@ -33,6 +34,7 @@     , delete     , filter     , restrictKeys+    , withoutKeys     , mapMaybe        -- * Query@@ -58,6 +60,7 @@        -- * Conversions     , toList+    , toAscList     , toMap     , keys     , keysSet@@ -124,6 +127,9 @@   length m = size m   {-# INLINABLE length #-} +  null (Map m _) = null m+  {-# INLINABLE null #-}+ instance Ord k => Traversable (Map k) where   traverse f m = traverseWithKey (\_ v -> f v) m   {-# INLINABLE traverse #-}@@ -161,6 +167,10 @@      toList = Dhall.Map.toList +-- | Create an empty `Map`+empty :: Ord k => Map k v+empty = mempty+ {-| Create a `Map` from a single key-value pair  >>> singleton "A" 1@@ -369,6 +379,23 @@     ks' = filterKeys (\k -> Data.Set.member k s) ks {-# INLINABLE restrictKeys #-} +{-| Remove all keys in a @"Data.Set".'Set'@ from a 'Map'++>>> withoutKeys (fromList [("A",1),("B",2)]) (Data.Set.fromList ["A"])+fromList [("B",2)]+-}+withoutKeys :: Ord k => Map k a -> Data.Set.Set k -> Map k a+withoutKeys (Map m ks) s = Map m' ks'+  where+#if MIN_VERSION_containers(0,5,8)+    m' = Data.Map.withoutKeys m s+#else+    m' = Data.Map.filterWithKey (\k _ -> Data.Set.notMember k s) m+#endif++    ks' = filterKeys (\k -> Data.Set.notMember k s) ks+{-# INLINABLE withoutKeys #-}+ {-| Transform all values in a `Map` using the supplied function, deleting the     key if the function returns `Nothing` @@ -630,6 +657,12 @@ toList (Map m Sorted)        = Data.Map.toList m toList (Map m (Original ks)) = fmap (\k -> (k, m Data.Map.! 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+{-# INLINABLE toAscList #-}  {-| Convert a @"Dhall.Map".`Map`@ to a @"Data.Map".`Data.Map.Map`@ 
+ src/Dhall/Normalize.hs view
@@ -0,0 +1,1239 @@+{-# LANGUAGE BangPatterns       #-}+{-# LANGUAGE OverloadedStrings  #-}+{-# LANGUAGE RankNTypes         #-}++module Dhall.Normalize (+      alphaNormalize+    , normalize+    , normalizeWith+    , normalizeWithM+    , Normalizer+    , NormalizerM+    , ReifiedNormalizer (..)+    , judgmentallyEqual+    , subst+    , shift+    , isNormalized+    , isNormalizedWith+    , freeIn+    ) where++import Control.Applicative (empty)+import Data.Foldable+import Data.Functor.Identity (Identity(..))+import Data.Semigroup (Semigroup(..))+import Data.Sequence (ViewL(..), ViewR(..))+import Data.Traversable+import Dhall.Syntax (Expr(..), Var(..), Binding(Binding), Chunks(..), DhallDouble(..), Const(..))+import Instances.TH.Lift ()+import Prelude hiding (succ)++import qualified Data.Sequence+import qualified Data.Set+import qualified Data.Text+import qualified Dhall.Eval    as Eval+import qualified Dhall.Map+import qualified Dhall.Set+import qualified Dhall.Syntax  as Syntax++{-| Returns `True` if two expressions are α-equivalent and β-equivalent and+    `False` otherwise++    `judgmentallyEqual` can fail with an `error` if you compare ill-typed+    expressions+-}+judgmentallyEqual :: Eq a => Expr s a -> Expr t a -> Bool+judgmentallyEqual = Eval.judgmentallyEqual+{-# INLINE judgmentallyEqual #-}++{-| `shift` is used by both normalization and type-checking to avoid variable+    capture by shifting variable indices++    For example, suppose that you were to normalize the following expression:++> λ(a : Type) → λ(x : a) → (λ(y : a) → λ(x : a) → y) x++    If you were to substitute @y@ with @x@ without shifting any variable+    indices, then you would get the following incorrect result:++> λ(a : Type) → λ(x : a) → λ(x : a) → x  -- Incorrect normalized form++    In order to substitute @x@ in place of @y@ we need to `shift` @x@ by @1@ in+    order to avoid being misinterpreted as the @x@ bound by the innermost+    lambda.  If we perform that `shift` then we get the correct result:++> λ(a : Type) → λ(x : a) → λ(x : a) → x@1++    As a more worked example, suppose that you were to normalize the following+    expression:++>     λ(a : Type)+> →   λ(f : a → a → a)+> →   λ(x : a)+> →   λ(x : a)+> →   (λ(x : a) → f x x@1) x@1++    The correct normalized result would be:++>     λ(a : Type)+> →   λ(f : a → a → a)+> →   λ(x : a)+> →   λ(x : a)+> →   f x@1 x++    The above example illustrates how we need to both increase and decrease+    variable indices as part of substitution:++    * We need to increase the index of the outer @x\@1@ to @x\@2@ before we+      substitute it into the body of the innermost lambda expression in order+      to avoid variable capture.  This substitution changes the body of the+      lambda expression to @(f x\@2 x\@1)@++    * We then remove the innermost lambda and therefore decrease the indices of+      both @x@s in @(f x\@2 x\@1)@ to @(f x\@1 x)@ in order to reflect that one+      less @x@ variable is now bound within that scope++    Formally, @(shift d (V x n) e)@ modifies the expression @e@ by adding @d@ to+    the indices of all variables named @x@ whose indices are greater than+    @(n + m)@, where @m@ is the number of bound variables of the same name+    within that scope++    In practice, @d@ is always @1@ or @-1@ because we either:++    * increment variables by @1@ to avoid variable capture during substitution+    * decrement variables by @1@ when deleting lambdas after substitution++    @n@ starts off at @0@ when substitution begins and increments every time we+    descend into a lambda or let expression that binds a variable of the same+    name in order to avoid shifting the bound variables by mistake.+-}+shift :: Int -> Var -> Expr s a -> Expr s a+shift _ _ (Const a) = Const a+shift d (V x n) (Var (V x' n')) = Var (V x' n'')+  where+    n'' = if x == x' && n <= n' then n' + d else n'+shift d (V x n) (Lam x' _A b) = Lam x' _A' b'+  where+    _A' = shift d (V x n ) _A+    b'  = shift d (V x n') b+      where+        n' = if x == x' then n + 1 else n+shift d (V x n) (Pi x' _A _B) = Pi x' _A' _B'+  where+    _A' = shift d (V x n ) _A+    _B' = shift d (V x n') _B+      where+        n' = if x == x' then n + 1 else n+shift d v (App f a) = App f' a'+  where+    f' = shift d v f+    a' = shift d v a+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 (Annot a b) = Annot a' b'+  where+    a' = shift d v a+    b' = shift d v b+shift _ _ Bool = Bool+shift _ _ (BoolLit a) = BoolLit a+shift d v (BoolAnd a b) = BoolAnd a' b'+  where+    a' = shift d v a+    b' = shift d v b+shift d v (BoolOr a b) = BoolOr a' b'+  where+    a' = shift d v a+    b' = shift d v b+shift d v (BoolEQ a b) = BoolEQ a' b'+  where+    a' = shift d v a+    b' = shift d v b+shift d v (BoolNE a b) = BoolNE a' b'+  where+    a' = shift d v a+    b' = shift d v b+shift d v (BoolIf a b c) = BoolIf a' b' c'+  where+    a' = shift d v a+    b' = shift d v b+    c' = shift d v c+shift _ _ Natural = Natural+shift _ _ (NaturalLit a) = NaturalLit a+shift _ _ NaturalFold = NaturalFold+shift _ _ NaturalBuild = NaturalBuild+shift _ _ NaturalIsZero = NaturalIsZero+shift _ _ NaturalEven = NaturalEven+shift _ _ NaturalOdd = NaturalOdd+shift _ _ NaturalToInteger = NaturalToInteger+shift _ _ NaturalShow = NaturalShow+shift _ _ NaturalSubtract = NaturalSubtract+shift d v (NaturalPlus a b) = NaturalPlus a' b'+  where+    a' = shift d v a+    b' = shift d v b+shift d v (NaturalTimes a b) = NaturalTimes a' b'+  where+    a' = shift d v a+    b' = shift d v b+shift _ _ Integer = Integer+shift _ _ (IntegerLit a) = IntegerLit a+shift _ _ IntegerClamp = IntegerClamp+shift _ _ IntegerNegate = IntegerNegate+shift _ _ IntegerShow = IntegerShow+shift _ _ IntegerToDouble = IntegerToDouble+shift _ _ Double = Double+shift _ _ (DoubleLit a) = DoubleLit a+shift _ _ DoubleShow = DoubleShow+shift _ _ Text = Text+shift d v (TextLit (Chunks a b)) = TextLit (Chunks a' b)+  where+    a' = fmap (fmap (shift d v)) a+shift d v (TextAppend a b) = TextAppend a' b'+  where+    a' = shift d v a+    b' = shift d v b+shift _ _ TextShow = TextShow+shift _ _ List = List+shift d v (ListLit a b) = ListLit a' b'+  where+    a' = fmap (shift d v) a+    b' = fmap (shift d v) b+shift _ _ ListBuild = ListBuild+shift d v (ListAppend a b) = ListAppend a' b'+  where+    a' = shift d v a+    b' = shift d v b+shift _ _ ListFold = ListFold+shift _ _ ListLength = ListLength+shift _ _ ListHead = ListHead+shift _ _ ListLast = ListLast+shift _ _ ListIndexed = ListIndexed+shift _ _ ListReverse = ListReverse+shift _ _ Optional = Optional+shift d v (Some a) = Some a'+  where+    a' = shift d v a+shift _ _ None = None+shift _ _ OptionalFold = OptionalFold+shift _ _ OptionalBuild = OptionalBuild+shift d v (Record a) = Record a'+  where+    a' = fmap (shift d v) a+shift d v (RecordLit a) = RecordLit a'+  where+    a' = fmap (shift d v) a+shift d v (Union a) = Union a'+  where+    a' = fmap (fmap (shift d v)) a+shift d v (Combine a b) = Combine a' b'+  where+    a' = shift d v a+    b' = shift d v b+shift d v (CombineTypes a b) = CombineTypes a' b'+  where+    a' = shift d v a+    b' = shift d v b+shift d v (Prefer a b) = Prefer a' b'+  where+    a' = shift d v a+    b' = shift d v b+shift d v (RecordCompletion a b) = RecordCompletion a' b'+  where+    a' = shift d v a+    b' = shift d v b+shift d v (Merge a b c) = Merge a' b' c'+  where+    a' =       shift d v  a+    b' =       shift d v  b+    c' = fmap (shift d v) c+shift d v (ToMap a b) = ToMap a' b'+  where+    a' =       shift d v  a+    b' = fmap (shift d v) b+shift d v (Field a b) = Field a' b+  where+    a' = shift d v a+shift d v (Assert a) = Assert a'+  where+    a' = shift d v a+shift d v (Equivalent a b) = Equivalent a' b'+  where+    a' = shift d v a+    b' = shift d v b+shift d v (Project a b) = Project a' b'+  where+    a' =       shift d v  a+    b' = fmap (shift d v) b+shift d v (Note a b) = Note a b'+  where+    b' = shift d v b+shift d v (ImportAlt a b) = ImportAlt a' b'+  where+    a' = shift d v a+    b' = shift d v b+-- The Dhall compiler enforces that all embedded values are closed expressions+-- and `shift` does nothing to a closed expression+shift _ _ (Embed p) = Embed p++{-| Substitute all occurrences of a variable with an expression++> subst x C B  ~  B[x := C]+-}+subst :: Var -> Expr s a -> Expr s a -> Expr s a+subst _ _ (Const a) = Const a+subst (V x n) e (Lam y _A b) = Lam y _A' b'+  where+    _A' = subst (V x n )                  e  _A+    b'  = subst (V x n') (shift 1 (V y 0) e)  b+    n'  = if x == y then n + 1 else n+subst (V x n) e (Pi y _A _B) = Pi y _A' _B'+  where+    _A' = subst (V x n )                  e  _A+    _B' = subst (V x n') (shift 1 (V y 0) e) _B+    n'  = if x == y then n + 1 else n+subst v e (App f a) = App f' a'+  where+    f' = subst v e f+    a' = subst v e a+subst v e (Var v') = if v == v' then e else Var v'+subst (V x n) e (Let (Binding src0 f src1 mt src2 r) b) =+    Let (Binding src0 f src1 mt' src2 r') b'+  where+    b' = subst (V x n') (shift 1 (V f 0) e) b+      where+        n' = if x == f then n + 1 else n++    mt' = fmap (fmap (subst (V x n) e)) mt+    r'  =             subst (V x n) e  r+subst x e (Annot a b) = Annot a' b'+  where+    a' = subst x e a+    b' = subst x e b+subst _ _ Bool = Bool+subst _ _ (BoolLit a) = BoolLit a+subst x e (BoolAnd a b) = BoolAnd a' b'+  where+    a' = subst x e a+    b' = subst x e b+subst x e (BoolOr a b) = BoolOr a' b'+  where+    a' = subst x e a+    b' = subst x e b+subst x e (BoolEQ a b) = BoolEQ a' b'+  where+    a' = subst x e a+    b' = subst x e b+subst x e (BoolNE a b) = BoolNE a' b'+  where+    a' = subst x e a+    b' = subst x e b+subst x e (BoolIf a b c) = BoolIf a' b' c'+  where+    a' = subst x e a+    b' = subst x e b+    c' = subst x e c+subst _ _ Natural = Natural+subst _ _ (NaturalLit a) = NaturalLit a+subst _ _ NaturalFold = NaturalFold+subst _ _ NaturalBuild = NaturalBuild+subst _ _ NaturalIsZero = NaturalIsZero+subst _ _ NaturalEven = NaturalEven+subst _ _ NaturalOdd = NaturalOdd+subst _ _ NaturalToInteger = NaturalToInteger+subst _ _ NaturalShow = NaturalShow+subst _ _ NaturalSubtract = NaturalSubtract+subst x e (NaturalPlus a b) = NaturalPlus a' b'+  where+    a' = subst x e a+    b' = subst x e b+subst x e (NaturalTimes a b) = NaturalTimes a' b'+  where+    a' = subst x e a+    b' = subst x e b+subst _ _ Integer = Integer+subst _ _ (IntegerLit a) = IntegerLit a+subst _ _ IntegerClamp = IntegerClamp+subst _ _ IntegerNegate = IntegerNegate+subst _ _ IntegerShow = IntegerShow+subst _ _ IntegerToDouble = IntegerToDouble+subst _ _ Double = Double+subst _ _ (DoubleLit a) = DoubleLit a+subst _ _ DoubleShow = DoubleShow+subst _ _ Text = Text+subst x e (TextLit (Chunks a b)) = TextLit (Chunks a' b)+  where+    a' = fmap (fmap (subst x e)) a+subst x e (TextAppend a b) = TextAppend a' b'+  where+    a' = subst x e a+    b' = subst x e b+subst _ _ TextShow = TextShow+subst _ _ List = List+subst x e (ListLit a b) = ListLit a' b'+  where+    a' = fmap (subst x e) a+    b' = fmap (subst x e) b+subst x e (ListAppend a b) = ListAppend a' b'+  where+    a' = subst x e a+    b' = subst x e b+subst _ _ ListBuild = ListBuild+subst _ _ ListFold = ListFold+subst _ _ ListLength = ListLength+subst _ _ ListHead = ListHead+subst _ _ ListLast = ListLast+subst _ _ ListIndexed = ListIndexed+subst _ _ ListReverse = ListReverse+subst _ _ Optional = Optional+subst x e (Some a) = Some a'+  where+    a' = subst x e a+subst _ _ None = None+subst _ _ OptionalFold = OptionalFold+subst _ _ OptionalBuild = OptionalBuild+subst x e (Record kts) = Record kts'+  where+    kts' = fmap (subst x e) kts+subst x e (RecordLit kvs) = RecordLit kvs'+  where+    kvs' = fmap (subst x e) kvs+subst x e (Union kts) = Union kts'+  where+    kts' = fmap (fmap (subst x e)) kts+subst x e (Combine a b) = Combine a' b'+  where+    a' = subst x e a+    b' = subst x e b+subst x e (CombineTypes a b) = CombineTypes a' b'+  where+    a' = subst x e a+    b' = subst x e b+subst x e (Prefer a b) = Prefer a' b'+  where+    a' = subst x e a+    b' = subst x e b+subst x e (RecordCompletion a b) = RecordCompletion a' b'+  where+    a' = subst x e a+    b' = subst x e b+subst x e (Merge a b c) = Merge a' b' c'+  where+    a' =       subst x e  a+    b' =       subst x e  b+    c' = fmap (subst x e) c+subst x e (ToMap a b) = ToMap a' b'+  where+    a' =       subst x e  a+    b' = fmap (subst x e) b+subst x e (Field a b) = Field a' b+  where+    a' = subst x e a+subst x e (Project a b) = Project a' b'+  where+    a' =       subst x e  a+    b' = fmap (subst x e) b+subst x e (Assert a) = Assert a'+  where+    a' = subst x e a+subst x e (Equivalent a b) = Equivalent a' b'+  where+    a' = subst x e a+    b' = subst x e b+subst x e (Note a b) = Note a b'+  where+    b' = subst x e b+subst x e (ImportAlt a b) = ImportAlt a' b'+  where+    a' = subst x e a+    b' = subst x e b+-- The Dhall compiler enforces that all embedded values are closed expressions+-- and `subst` does nothing to a closed expression+subst _ _ (Embed p) = Embed p++{-| This function is used to determine whether folds like @Natural/fold@ or+    @List/fold@ should be lazy or strict in their accumulator based on the type+    of the accumulator++    If this function returns `True`, then they will be strict in their+    accumulator since we can guarantee an upper bound on the amount of work to+    normalize the accumulator on each step of the loop.  If this function+    returns `False` then they will be lazy in their accumulator and only+    normalize the final result at the end of the fold+-}+boundedType :: Expr s a -> Bool+boundedType Bool             = True+boundedType Natural          = True+boundedType Integer          = True+boundedType Double           = True+boundedType Text             = True+boundedType (App List _)     = False+boundedType (App Optional t) = boundedType t+boundedType (Record kvs)     = all boundedType kvs+boundedType (Union kvs)      = all (all boundedType) kvs+boundedType _                = False++{-| α-normalize an expression by renaming all bound variables to @\"_\"@ and+    using De Bruijn indices to distinguish them++>>> alphaNormalize (Lam "a" (Const Type) (Lam "b" (Const Type) (Lam "x" "a" (Lam "y" "b" "x"))))+Lam "_" (Const Type) (Lam "_" (Const Type) (Lam "_" (Var (V "_" 1)) (Lam "_" (Var (V "_" 1)) (Var (V "_" 1)))))++    α-normalization does not affect free variables:++>>> alphaNormalize "x"+Var (V "x" 0)++-}+alphaNormalize :: Expr s a -> Expr s a+alphaNormalize = Eval.alphaNormalize+{-# INLINE alphaNormalize #-}++{-| Reduce an expression to its normal form, performing beta reduction++    `normalize` does not type-check the expression.  You may want to type-check+    expressions before normalizing them since normalization can convert an+    ill-typed expression into a well-typed expression.++    `normalize` can also fail with `error` if you normalize an ill-typed+    expression+-}+normalize :: Eq a => Expr s a -> Expr t a+normalize = Eval.normalize+{-# INLINE normalize #-}++{-| Reduce an expression to its normal form, performing beta reduction and applying+    any custom definitions.++    `normalizeWith` is designed to be used with function `typeWith`. The `typeWith`+    function allows typing of Dhall functions in a custom typing context whereas+    `normalizeWith` allows evaluating Dhall expressions in a custom context.++    To be more precise `normalizeWith` applies the given normalizer when it finds an+    application term that it cannot reduce by other means.++    Note that the context used in normalization will determine the properties of normalization.+    That is, if the functions in custom context are not total then the Dhall language, evaluated+    with those functions is not total either.++    `normalizeWith` can fail with an `error` if you normalize an ill-typed+    expression+-}+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++{-| This function generalizes `normalizeWith` by allowing the custom normalizer+    to use an arbitrary `Monad`++    `normalizeWithM` can fail with an `error` if you normalize an ill-typed+    expression+-}+normalizeWithM+    :: (Monad m, Eq a) => NormalizerM m a -> Expr s a -> m (Expr t a)+normalizeWithM ctx e0 = loop (Syntax.denote e0)+ where+ loop e =  case e of+    Const k -> pure (Const k)+    Var v -> pure (Var v)+    Lam x _A b -> Lam 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+              f' <- loop f+              a' <- loop a+              case f' of+                Lam x _A b₀ -> do++                    let a₂ = shift 1 (V x 0) a'+                    let b₁ = subst (V x 0) a₂ b₀+                    let b₂ = shift (-1) (V x 0) b₁++                    loop b₂+                _ -> do+                  case App f' a' of+                    App NaturalFold (NaturalLit n) -> do+                        let natural = Var (V "natural" 0)+                        let go 0  x = x+                            go n' x = go (n'-1) (App (Var (V "succ" 0)) x)+                        let n' = go n (Var (V "zero" 0))+                        pure+                            (Lam "natural"+                                (Const Type)+                                (Lam "succ"+                                    (Pi "_" natural natural)+                                    (Lam "zero"+                                        natural+                                        n')))++                    App (App (App (App NaturalFold (NaturalLit n0)) t) succ') zero -> do+                      t' <- loop t+                      if boundedType t' then strict else lazy+                      where+                        strict =       strictLoop (fromIntegral n0 :: Integer)+                        lazy   = loop (  lazyLoop (fromIntegral n0 :: Integer))++                        strictLoop !0 = loop zero+                        strictLoop !n = App succ' <$> strictLoop (n - 1) >>= loop++                        lazyLoop !0 = zero+                        lazyLoop !n = App succ' (lazyLoop (n - 1))+                    App NaturalBuild g -> loop (App (App (App g Natural) succ) zero)+                      where+                        succ = Lam "n" Natural (NaturalPlus "n" (NaturalLit 1))++                        zero = NaturalLit 0+                    App NaturalIsZero (NaturalLit n) -> pure (BoolLit (n == 0))+                    App NaturalEven (NaturalLit n) -> pure (BoolLit (even n))+                    App NaturalOdd (NaturalLit n) -> pure (BoolLit (odd n))+                    App NaturalToInteger (NaturalLit n) -> pure (IntegerLit (toInteger n))+                    App NaturalShow (NaturalLit n) ->+                        pure (TextLit (Chunks [] (Data.Text.pack (show n))))+                    App (App NaturalSubtract (NaturalLit x)) (NaturalLit y)+                        | y >= x    -> pure (NaturalLit (subtract x y))+                        | otherwise -> pure (NaturalLit 0)+                    App (App NaturalSubtract (NaturalLit 0)) y -> pure y+                    App (App NaturalSubtract _) (NaturalLit 0) -> pure (NaturalLit 0)+                    App (App NaturalSubtract x) y | Eval.judgmentallyEqual x y -> pure (NaturalLit 0)+                    App IntegerClamp (IntegerLit n)+                        | 0 <= n -> pure (NaturalLit (fromInteger n))+                        | otherwise -> pure (NaturalLit 0)+                    App IntegerNegate (IntegerLit n) ->+                        pure (IntegerLit (negate n))+                    App IntegerShow (IntegerLit n)+                        | 0 <= n    -> pure (TextLit (Chunks [] ("+" <> Data.Text.pack (show n))))+                        | otherwise -> pure (TextLit (Chunks [] (Data.Text.pack (show n))))+                    -- `(read . show)` is used instead of `fromInteger` because `read` uses+                    -- the correct rounding rule.+                    -- See https://gitlab.haskell.org/ghc/ghc/issues/17231.+                    App IntegerToDouble (IntegerLit n) -> pure (DoubleLit ((DhallDouble . read . show) n))+                    App DoubleShow (DoubleLit (DhallDouble n)) ->+                        pure (TextLit (Chunks [] (Data.Text.pack (show n))))+                    App (App OptionalBuild _A₀) g ->+                        loop (App (App (App g optional) just) nothing)+                      where+                        optional = App Optional _A₀++                        just = Lam "a" _A₀ (Some "a")++                        nothing = App None _A₀+                    App (App ListBuild _A₀) g -> loop (App (App (App g list) cons) nil)+                      where+                        _A₁ = shift 1 "a" _A₀++                        list = App List _A₀++                        cons =+                            Lam "a" _A₀+                                (Lam "as"+                                    (App List _A₁)+                                    (ListAppend (ListLit Nothing (pure "a")) "as")+                                )++                        nil = ListLit (Just (App List _A₀)) empty+                    App (App ListFold t) (ListLit _ xs) -> do+                        t' <- loop t+                        let list = Var (V "list" 0)+                        let lam term =+                                Lam "list" (Const Type)+                                    (Lam "cons" (Pi "_" t' (Pi "_" list list))+                                        (Lam "nil" list term))+                        term <- foldrM+                            (\x acc -> do+                                x' <- loop x+                                pure (App (App (Var (V "cons" 0)) x') acc))+                            (Var (V "nil" 0))+                            xs+                        pure (lam term)+                    App (App (App (App (App ListFold _) (ListLit _ xs)) t) cons) nil -> do+                      t' <- loop t+                      if boundedType t' then strict else lazy+                      where+                        strict =       foldr strictCons strictNil xs+                        lazy   = loop (foldr   lazyCons   lazyNil xs)++                        strictNil = loop nil+                        lazyNil   =      nil++                        strictCons y ys = do+                          App (App cons y) <$> ys >>= loop+                        lazyCons   y ys =       App (App cons y) ys+                    App (App ListLength _) (ListLit _ ys) ->+                        pure (NaturalLit (fromIntegral (Data.Sequence.length ys)))+                    App (App ListHead t) (ListLit _ ys) -> loop o+                      where+                        o = case Data.Sequence.viewl ys of+                                y :< _ -> Some y+                                _      -> App None t+                    App (App ListLast t) (ListLit _ ys) -> loop o+                      where+                        o = case Data.Sequence.viewr ys of+                                _ :> y -> Some y+                                _      -> App None t+                    App (App ListIndexed _A₀) (ListLit _ as₀) -> loop (ListLit t as₁)+                      where+                        as₁ = Data.Sequence.mapWithIndex adapt as₀++                        _A₂ = Record (Dhall.Map.fromList kts)+                          where+                            kts = [ ("index", Natural)+                                  , ("value", _A₀)+                                  ]++                        t | null as₀  = Just (App List _A₂)+                          | otherwise = Nothing++                        adapt n a_ =+                            RecordLit (Dhall.Map.fromList kvs)+                          where+                            kvs = [ ("index", NaturalLit (fromIntegral n))+                                  , ("value", a_)+                                  ]+                    App (App ListReverse _) (ListLit t xs) ->+                        loop (ListLit t (Data.Sequence.reverse xs))++                    App (App OptionalFold t0) x0 -> do+                        t1 <- loop t0+                        let optional = Var (V "optional" 0)+                        let lam term = (Lam "optional"+                                           (Const Type)+                                           (Lam "some"+                                               (Pi "_" t1 optional)+                                               (Lam "none" optional term)))+                        x1 <- loop x0+                        pure $ case x1 of+                            App None _ -> lam (Var (V "none" 0))+                            Some x'    -> lam (App (Var (V "some" 0)) x')+                            _          -> App (App OptionalFold t1) x1++                    App TextShow (TextLit (Chunks [] oldText)) ->+                        loop (TextLit (Chunks [] newText))+                      where+                        newText = Eval.textShow oldText+                    _ -> 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'  = shift   1  (V f 0) r+        b'  = subst (V f 0) r' b+        b'' = 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++        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)] ""))+    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+    OptionalFold -> pure OptionalFold+    OptionalBuild -> pure OptionalBuild+    Record kts -> Record . Dhall.Map.sort <$> kts'+      where+        kts' = traverse loop kts+    RecordLit kvs -> RecordLit . Dhall.Map.sort <$> kvs'+      where+        kvs' = traverse loop kvs+    Union kts -> Union . Dhall.Map.sort <$> kts'+      where+        kts' = traverse (traverse loop) kts+    Combine 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 decide m n)+        decide l r =+            Combine 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 decide m n)+        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 l r+    RecordCompletion x y -> do+        loop (Annot (Prefer (Field x "default") y) (Field x "Type"))+    Merge x y t      -> do+        x' <- loop x+        y' <- loop y+        case x' of+            RecordLit kvsX ->+                case y' of+                    Field (Union ktsY) kY ->+                        case Dhall.Map.lookup kY ktsY of+                            Just Nothing ->+                                case Dhall.Map.lookup kY kvsX of+                                    Just vX -> return vX+                                    Nothing -> Merge x' y' <$> t'+                            _ ->+                                Merge x' y' <$> t'+                    App (Field (Union ktsY) kY) vY ->+                        case Dhall.Map.lookup kY ktsY of+                            Just (Just _) ->+                                case Dhall.Map.lookup kY kvsX of+                                    Just vX -> loop (App vX vY)+                                    Nothing -> Merge x' y' <$> t'+                            _ ->+                                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"  , TextLit (Chunks [] key))+                                , ("mapValue", value                  )+                                ]+                            )++                let keyValues = Data.Sequence.fromList (map entry (Dhall.Map.toList kvsX))++                let listType = case t' of+                        Just _ | null keyValues ->+                            t'+                        _ ->+                            Nothing++                return (ListLit listType keyValues)+            _ -> do+                return (ToMap x' t')+    Field r 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 v+                    Nothing -> Field <$> (RecordLit <$> traverse loop kvs) <*> pure x+            Project r_ _ -> loop (Field r_ x)+            Prefer (RecordLit kvs) r_ -> case Dhall.Map.lookup x kvs of+                Just v -> pure (Field (Prefer (singletonRecordLit v) r_) x)+                Nothing -> loop (Field r_ x)+            Prefer l (RecordLit kvs) -> case Dhall.Map.lookup x kvs of+                Just v -> pure v+                Nothing -> loop (Field l x)+            Combine (RecordLit kvs) r_ -> case Dhall.Map.lookup x kvs of+                Just v -> pure (Field (Combine (singletonRecordLit v) r_) x)+                Nothing -> loop (Field r_ x)+            Combine l (RecordLit kvs) -> case Dhall.Map.lookup x kvs of+                Just v -> pure (Field (Combine l (singletonRecordLit v)) x)+                Nothing -> loop (Field l x)+            _ -> pure (Field r' x)+    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 l' r')+            _ | null fields -> pure (RecordLit mempty)+              | otherwise   -> pure (Project x' (Left (Dhall.Set.sort fields)))+    Project r (Right e1) -> do+        e2 <- loop e1++        case e2 of+            Record kts -> do+                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++        pure (Assert t')+    Equivalent l r -> do+        l' <- loop l+        r' <- loop r++        pure (Equivalent l' r')+    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.+type NormalizerM m a = forall s. Expr s a -> m (Maybe (Expr s a))++-- | An variation on `NormalizerM` for pure normalizers+type Normalizer a = NormalizerM Identity a++-- | A reified 'Normalizer', which can be stored in structures without+-- running into impredicative polymorphism.+newtype ReifiedNormalizer a = ReifiedNormalizer+  { getReifiedNormalizer :: Normalizer a }++-- | Check if an expression is in a normal form given a context of evaluation.+--   Unlike `isNormalized`, this will fully normalize and traverse through the expression.+--+--   It is much more efficient to use `isNormalized`.+--+--  `isNormalizedWith` can fail with an `error` if you check an ill-typed+--  expression+isNormalizedWith :: (Eq s, Eq a) => Normalizer a -> Expr s a -> Bool+isNormalizedWith ctx e = e == normalizeWith (Just (ReifiedNormalizer ctx)) e++-- | Quickly check if an expression is in normal form+--+-- Given a well-typed expression @e@, @'isNormalized' e@ is equivalent to+-- @e == 'normalize' e@.+--+-- Given an ill-typed expression, 'isNormalized' may fail with an error, or+-- evaluate to either False or True!+isNormalized :: Eq a => Expr s a -> Bool+isNormalized e0 = loop (Syntax.denote e0)+  where+    loop e = case e of+      Const _ -> True+      Var _ -> True+      Lam _ a b -> loop a && loop b+      Pi _ a b -> loop a && loop b+      App f a -> loop f && loop a && case App f a of+          App (Lam _ _ _) _ -> False+          App (App (App (App NaturalFold (NaturalLit _)) _) _) _ -> False+          App NaturalFold (NaturalLit _) -> False+          App NaturalBuild _ -> False+          App NaturalIsZero (NaturalLit _) -> False+          App NaturalEven (NaturalLit _) -> False+          App NaturalOdd (NaturalLit _) -> False+          App NaturalShow (NaturalLit _) -> False+          App (App NaturalSubtract (NaturalLit _)) (NaturalLit _) -> False+          App (App NaturalSubtract (NaturalLit 0)) _ -> False+          App (App NaturalSubtract _) (NaturalLit 0) -> False+          App (App NaturalSubtract x) y -> not (Eval.judgmentallyEqual x y)+          App NaturalToInteger (NaturalLit _) -> False+          App IntegerNegate (IntegerLit _) -> False+          App IntegerClamp (IntegerLit _) -> False+          App IntegerShow (IntegerLit _) -> False+          App IntegerToDouble (IntegerLit _) -> False+          App DoubleShow (DoubleLit _) -> False+          App (App OptionalBuild _) _ -> False+          App (App ListBuild _) _ -> False+          App (App ListFold _) (ListLit _ _) -> False+          App (App ListLength _) (ListLit _ _) -> False+          App (App ListHead _) (ListLit _ _) -> False+          App (App ListLast _) (ListLit _ _) -> False+          App (App ListIndexed _) (ListLit _ _) -> False+          App (App ListReverse _) (ListLit _ _) -> False+          App (App OptionalFold _) (Some _) -> False+          App (App OptionalFold _) (App None _) -> False+          App TextShow (TextLit (Chunks [] _)) ->+              False+          _ -> True+      Let _ _ -> False+      Annot _ _ -> False+      Bool -> True+      BoolLit _ -> True+      BoolAnd x y -> loop x && loop y && decide x y+        where+          decide (BoolLit _)  _          = False+          decide  _          (BoolLit _) = False+          decide  l           r          = not (Eval.judgmentallyEqual l r)+      BoolOr x y -> loop x && loop y && decide x y+        where+          decide (BoolLit _)  _          = False+          decide  _          (BoolLit _) = False+          decide  l           r          = not (Eval.judgmentallyEqual l r)+      BoolEQ x y -> loop x && loop y && decide x y+        where+          decide (BoolLit True)  _             = False+          decide  _             (BoolLit True) = False+          decide  l              r             = not (Eval.judgmentallyEqual l r)+      BoolNE x y -> loop x && loop y && decide x y+        where+          decide (BoolLit False)  _               = False+          decide  _              (BoolLit False ) = False+          decide  l               r               = not (Eval.judgmentallyEqual l r)+      BoolIf x y z ->+          loop x && loop y && loop z && decide x y z+        where+          decide (BoolLit _)  _              _              = False+          decide  _          (BoolLit True) (BoolLit False) = False+          decide  _           l              r              = not (Eval.judgmentallyEqual l r)+      Natural -> True+      NaturalLit _ -> True+      NaturalFold -> True+      NaturalBuild -> True+      NaturalIsZero -> True+      NaturalEven -> True+      NaturalOdd -> True+      NaturalShow -> True+      NaturalSubtract -> True+      NaturalToInteger -> True+      NaturalPlus x y -> loop x && loop y && decide x y+        where+          decide (NaturalLit 0)  _             = False+          decide  _             (NaturalLit 0) = False+          decide (NaturalLit _) (NaturalLit _) = False+          decide  _              _             = True+      NaturalTimes x y -> loop x && loop y && decide x y+        where+          decide (NaturalLit 0)  _             = False+          decide  _             (NaturalLit 0) = False+          decide (NaturalLit 1)  _             = False+          decide  _             (NaturalLit 1) = False+          decide (NaturalLit _) (NaturalLit _) = False+          decide  _              _             = True+      Integer -> True+      IntegerLit _ -> True+      IntegerClamp -> True+      IntegerNegate -> True+      IntegerShow -> True+      IntegerToDouble -> True+      Double -> True+      DoubleLit _ -> True+      DoubleShow -> True+      Text -> True+      TextLit (Chunks [("", _)] "") -> False+      TextLit (Chunks xys _) -> all (all check) xys+        where+          check y = loop y && case y of+              TextLit _ -> False+              _         -> True+      TextAppend _ _ -> False+      TextShow -> True+      List -> True+      ListLit t es -> all loop t && all loop es+      ListAppend x y -> loop x && loop y && decide x y+        where+          decide (ListLit _ m)  _            | Data.Sequence.null m = False+          decide  _            (ListLit _ n) | Data.Sequence.null n = False+          decide (ListLit _ _) (ListLit _ _)                        = False+          decide  _             _                                   = True+      ListBuild -> True+      ListFold -> True+      ListLength -> True+      ListHead -> True+      ListLast -> True+      ListIndexed -> True+      ListReverse -> True+      Optional -> True+      Some a -> loop a+      None -> True+      OptionalFold -> True+      OptionalBuild -> True+      Record kts -> Dhall.Map.isSorted kts && all loop kts+      RecordLit kvs -> Dhall.Map.isSorted kvs && all loop kvs+      Union kts -> Dhall.Map.isSorted kts && all (all loop) kts+      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+        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+        where+          decide (RecordLit m) _ | Data.Foldable.null m = False+          decide _ (RecordLit n) | Data.Foldable.null n = False+          decide (RecordLit _) (RecordLit _) = False+          decide l r = not (Eval.judgmentallyEqual l r)+      RecordCompletion _ _ -> False+      Merge x y t -> loop x && loop y && all loop t+      ToMap x t -> case x of+          RecordLit _ -> False+          _ -> loop x && all loop t+      Field r k -> 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+          _ -> loop r+      Project r p -> loop r &&+          case p of+              Left s -> case r of+                  RecordLit _ -> False+                  Project _ _ -> False+                  Prefer _ (RecordLit _) -> False+                  _ -> not (Dhall.Set.null s) && Dhall.Set.isSorted s+              Right e' -> case e' of+                  Record _ -> False+                  _ -> loop e'+      Assert t -> loop t+      Equivalent l r -> loop l && loop r+      Note _ e' -> loop e'+      ImportAlt _ _ -> False+      Embed _ -> True++{-| Detect if the given variable is free within the given expression++>>> "x" `freeIn` "x"+True+>>> "x" `freeIn` "y"+False+>>> "x" `freeIn` Lam "x" (Const Type) "x"+False+-}+freeIn :: Eq a => Var -> Expr s a -> Bool+variable@(V var i) `freeIn` expression =+    subst variable (Var (V var (i + 1))) strippedExpression+      /= strippedExpression+  where+    denote' :: Expr t b -> Expr () b+    denote' = Syntax.denote++    strippedExpression = denote' expression
src/Dhall/Parser.hs view
@@ -8,11 +8,13 @@       exprFromText     , exprAndHeaderFromText     , censor+    , createHeader      -- * Parsers     , expr, exprA      -- * Types+    , Header(..)     , Src(..)     , SourcedException(..)     , ParseError(..)@@ -23,7 +25,7 @@ import Data.Semigroup (Semigroup(..)) import Data.Text (Text) import Data.Void (Void)-import Dhall.Core+import Dhall.Syntax import Dhall.Src (Src(..)) import Prelude hiding (const, pi) import Text.Megaparsec (ParseErrorBundle(..), PosState(..))@@ -34,7 +36,7 @@ import qualified Text.Megaparsec  import Dhall.Parser.Combinators-import Dhall.Parser.Token+import Dhall.Parser.Token hiding (text) import Dhall.Parser.Expression  -- | Parser for a top-level Dhall expression@@ -48,11 +50,7 @@  -- | A parsing error data ParseError = ParseError {-#if MIN_VERSION_megaparsec(7, 0, 0)       unwrap :: Text.Megaparsec.ParseErrorBundle Text Void-#else-      unwrap :: Text.Megaparsec.ParseError Char Void-#endif     , input  :: Text     } @@ -76,11 +74,7 @@  instance Show ParseError where     show (ParseError {..}) =-#if MIN_VERSION_megaparsec(7, 0, 0)       "\n\ESC[1;31mError\ESC[0m: Invalid input\n\n" <> Text.Megaparsec.errorBundlePretty unwrap-#else-      "\n\ESC[1;31mError\ESC[0m: Invalid input\n\n" <> Text.Megaparsec.parseErrorPretty unwrap-#endif  instance Exception ParseError @@ -92,6 +86,17 @@   -> Either ParseError (Expr Src Import) exprFromText delta text = fmap snd (exprAndHeaderFromText delta text) +-- | A header corresponds to the leading comment at the top of a Dhall file.+--+-- The header includes comment characters but is stripped of leading spaces and+-- trailing newlines+newtype Header = Header Text deriving Show++-- | Create a header with stripped leading spaces and trailing newlines+createHeader :: Text -> Header+createHeader =+    Header . Data.Text.dropWhile Data.Char.isSpace . Data.Text.dropWhileEnd (/= '\n')+ {-| Like `exprFromText` but also returns the leading comments and whitespace     (i.e. header) up to the last newline before the code begins @@ -108,10 +113,10 @@     :: String -- ^ User-friendly name describing the input expression,               --   used in parsing error messages     -> Text   -- ^ Input expression to parse-    -> Either ParseError (Text, Expr Src Import)+    -> Either ParseError (Header, Expr Src Import) exprAndHeaderFromText delta text = case result of     Left errInfo   -> Left (ParseError { unwrap = errInfo, input = text })-    Right (txt, r) -> Right (stripHeader txt, r)+    Right (txt, r) -> Right (createHeader txt, r)   where     parser = do         (bytes, _) <- Text.Megaparsec.match whitespace@@ -120,5 +125,3 @@         return (bytes, r)      result = Text.Megaparsec.parse (unParser parser) delta text--    stripHeader = Data.Text.dropWhile Data.Char.isSpace . Data.Text.dropWhileEnd (/= '\n')
src/Dhall/Parser/Combinators.hs view
@@ -24,15 +24,11 @@ import qualified Data.Char import qualified Data.Set import qualified Data.Text-import qualified Data.Text.Prettyprint.Doc               as Pretty import qualified Data.Text.Prettyprint.Doc.Render.String as Pretty import qualified Dhall.Map import qualified Dhall.Pretty import qualified Dhall.Set import qualified Text.Megaparsec-#if !MIN_VERSION_megaparsec(7, 0, 0)-import qualified Text.Megaparsec.Char as Text.Megaparsec (satisfy)-#endif import qualified Text.Megaparsec.Char import qualified Text.Parser.Char import qualified Text.Parser.Combinators@@ -49,7 +45,7 @@         <>  "\n"         <>  "\n"         <>  Pretty.renderString-                (Pretty.layoutPretty Dhall.Pretty.layoutOpts (pretty source))+                (Dhall.Pretty.layout (pretty source))  -- | Doesn't force the 'Text' part laxSrcEq :: Src -> Src -> Bool@@ -127,9 +123,13 @@     -- {-# 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) @@ -197,11 +197,7 @@    notChar = Text.Megaparsec.Char.char -#if MIN_VERSION_megaparsec(7, 0, 0)   anyChar = Text.Megaparsec.anySingle-#else-  anyChar = Text.Megaparsec.Char.anyChar-#endif    string = fmap Data.Text.unpack . Text.Megaparsec.Char.string . fromString 
src/Dhall/Parser/Expression.hs view
@@ -10,11 +10,12 @@  import Control.Applicative (Alternative(..), optional) import Data.ByteArray.Encoding (Base(..))+import Data.Foldable (foldl') import Data.Functor (void) import Data.List.NonEmpty (NonEmpty(..)) import Data.Semigroup (Semigroup(..)) import Data.Text (Text)-import Dhall.Core+import Dhall.Syntax import Dhall.Src (Src(..)) import Prelude hiding (const, pi) import Text.Parser.Combinators (choice, try, (<?>))@@ -31,10 +32,6 @@ import qualified Data.Text.Encoding import qualified Dhall.Crypto import qualified Text.Megaparsec-#if !MIN_VERSION_megaparsec(7, 0, 0)-import qualified Text.Megaparsec.Char    as Text.Megaparsec-#endif-import qualified Text.Parser.Char  import Dhall.Parser.Combinators import Dhall.Parser.Token@@ -43,31 +40,19 @@ getSourcePos :: Text.Megaparsec.MonadParsec e s m =>                 m Text.Megaparsec.SourcePos getSourcePos =-#if MIN_VERSION_megaparsec(7, 0, 0)     Text.Megaparsec.getSourcePos-#else-    Text.Megaparsec.getPosition-#endif {-# INLINE getSourcePos #-}  -- | Get the current source offset (in tokens) getOffset :: Text.Megaparsec.MonadParsec e s m => m Int-#if MIN_VERSION_megaparsec(7, 0, 0) getOffset = Text.Megaparsec.stateOffset <$> Text.Megaparsec.getParserState-#else-getOffset = Text.Megaparsec.stateTokensProcessed <$> Text.Megaparsec.getParserState-#endif {-# INLINE getOffset #-}  -- | Set the current source offset setOffset :: Text.Megaparsec.MonadParsec e s m => Int -> m ()-#if MIN_VERSION_megaparsec(7, 0, 0)-setOffset o = Text.Megaparsec.updateParserState $ \(Text.Megaparsec.State s _ pst) ->-  Text.Megaparsec.State s o pst-#else-setOffset o = Text.Megaparsec.updateParserState $ \(Text.Megaparsec.State s p _ stw) ->-  Text.Megaparsec.State s p o stw-#endif+setOffset o = Text.Megaparsec.updateParserState $ \state ->+    state+        { Text.Megaparsec.stateOffset = o } {-# INLINE setOffset #-}  {-| Wrap a `Parser` to still match the same text but return only the `Src`@@ -129,9 +114,7 @@ parsers :: Parser a -> Parsers a parsers embedded = Parsers {..}   where-    completeExpression_ = do-        whitespace-        expression+    completeExpression_ = whitespace *> expression <* whitespace      expression =         noted@@ -147,53 +130,65 @@       where         alternative0 = do             _lambda+            whitespace             _openParens+            whitespace             a <- label+            whitespace             _colon+            nonemptyWhitespace             b <- expression+            whitespace             _closeParens+            whitespace             _arrow+            whitespace             c <- expression             return (Lam a b c)          alternative1 = do-            _if+            try (_if *> nonemptyWhitespace)             a <- expression-            _then+            whitespace+            try (_then *> nonemptyWhitespace)             b <- expression-            _else+            whitespace+            try (_else *> nonemptyWhitespace)             c <- expression             return (BoolIf a b c)          alternative2 = do             let binding = do-                    _letOnly--                    src0 <- src nonemptyWhitespace+                    src0 <- try (_let *> src nonemptyWhitespace) -                    c <- labelOnly+                    c <- label                      src1 <- src whitespace                      d <- optional (do-                        _colonOnly+                        _colon                          src2 <- src nonemptyWhitespace                          e <- expression++                        whitespace+                         return (Just src2, e) ) -                    _equalOnly+                    _equal                      src3 <- src whitespace                      f <- expression +                    whitespace+                     return (Binding (Just src0) c (Just src1) d (Just src3) f)              as <- Data.List.NonEmpty.some1 binding -            _in+            try (_in *> nonemptyWhitespace)              b <- expression @@ -214,22 +209,27 @@             --     (Let y …             --       (Note …             --         (Let z …-            return (Dhall.Core.wrapInLets as b)+            return (Dhall.Syntax.wrapInLets as b)          alternative3 = do-            _forall-            _openParens+            try (_forall *> whitespace *> _openParens)+            whitespace             a <- label+            whitespace             _colon+            nonemptyWhitespace             b <- expression+            whitespace             _closeParens+            whitespace             _arrow+            whitespace             c <- expression             return (Pi a b c)          alternative4 = do-            _assert-            _colon+            try (_assert *> whitespace *> _colon)+            nonemptyWhitespace             a <- expression             return (Assert a) @@ -238,81 +238,78 @@              let alternative4A = do                     _arrow+                    whitespace                     b <- expression+                    whitespace                     return (Pi "_" a b)              let alternative4B = do                     _colon-+                    nonemptyWhitespace                     b <- expression-                     case shallowDenote a of-                        ListLit _ [] ->+                        ListLit Nothing [] ->                             return (ListLit (Just b) [])-                        Merge c d _ ->+                        Merge c d Nothing ->                             return (Merge c d (Just b))-                        ToMap c _ ->+                        ToMap c Nothing ->                             return (ToMap c (Just b))                         _ -> return (Annot a b)              alternative4A <|> alternative4B <|> pure a -    operatorExpression = precedence0Expression+    operatorExpression =+        foldr makeOperatorExpression applicationExpression operatorParsers -    makeOperatorExpression subExpression operatorParser =+    makeOperatorExpression operatorParser subExpression =             noted (do                 a <- subExpression-                b <- Text.Megaparsec.many $ do-                    op <- operatorParser-                    r  <- subExpression -                    return (\l -> l `op` r)-                return (foldl (\x f -> f x) a b) )--    precedence0Operator =-                ImportAlt   <$ _importAlt-            <|> BoolOr      <$ _or-            <|> TextAppend  <$ _textAppend-            <|> NaturalPlus <$ _plus-            <|> ListAppend  <$ _listAppend--    precedence1Operator =-                BoolAnd     <$ _and-            <|> Combine     <$ _combine--    precedence2Operator =-                CombineTypes <$ _combineTypes-            <|> Prefer       <$ _prefer-            <|> NaturalTimes <$ _times-            <|> BoolEQ       <$ _doubleEqual+                whitespace -    precedence3Operator-            =   BoolNE     <$ _notEqual-            <|> Equivalent <$ _equivalent+                b <- Text.Megaparsec.many $ do+                    op <- operatorParser -    precedence0Expression =-            makeOperatorExpression precedence1Expression precedence0Operator+                    r  <- subExpression -    precedence1Expression =-            makeOperatorExpression precedence2Expression precedence1Operator+                    whitespace -    precedence2Expression =-            makeOperatorExpression precedence3Expression precedence2Operator+                    return (\l -> l `op` r)+                return (foldl' (\x f -> f x) a b)) -    precedence3Expression =-            makeOperatorExpression applicationExpression precedence3Operator+    operatorParsers :: [Parser (Expr s a -> Expr s a -> Expr s a)]+    operatorParsers =+        [ ImportAlt    <$ _importAlt    <* nonemptyWhitespace+        , BoolOr       <$ _or           <* whitespace+        , NaturalPlus  <$ _plus         <* nonemptyWhitespace+        , TextAppend   <$ _textAppend   <* whitespace+        , ListAppend   <$ _listAppend   <* whitespace+        , BoolAnd      <$ _and          <* whitespace+        , Combine      <$ _combine      <* whitespace+        , Prefer       <$ _prefer       <* whitespace+        , CombineTypes <$ _combineTypes <* whitespace+        , NaturalTimes <$ _times        <* whitespace+        , BoolEQ       <$ _doubleEqual  <* whitespace+        , BoolNE       <$ _notEqual     <* whitespace+        , Equivalent   <$ _equivalent   <* whitespace+        ]      applicationExpression = do-            f <-    (do _Some; return Some)+            f <-    (Some <$ try (_Some <* nonemptyWhitespace))                 <|> return id             a <- noted importExpression_-            b <- Text.Megaparsec.many (noted importExpression_)-            return (foldl app (f a) b)+            bs <- Text.Megaparsec.many . try $ do+                (sep, _) <- Text.Megaparsec.match nonemptyWhitespace+                b <- importExpression_+                return (sep, b)+            return (foldl' app (f a) bs)           where-            app nL@(Note (Src before _ bytesL) _) nR@(Note (Src _ after bytesR) _) =-                Note (Src before after (bytesL <> bytesR)) (App nL nR)-            app nL nR =-                App nL nR+            app a (sep, b)+                | Note (Src left _ bytesL) _ <- a+                , Note (Src _ right bytesR) _ <- b+                = Note (Src left right (bytesL <> sep <> bytesR)) (App a b)+            app a (_, b) =+                App a b      importExpression_ = noted (choice [ alternative0, alternative1 ])           where@@ -326,8 +323,10 @@         a <- selectorExpression          mb <- optional (do-            _doubleColon+            try (whitespace *> _doubleColon) +            whitespace+             selectorExpression )          case mb of@@ -337,7 +336,7 @@     selectorExpression = noted (do             a <- primitiveExpression -            let recordType = _openParens *> expression <* _closeParens+            let recordType = _openParens *> whitespace *> expression <* whitespace <* _closeParens              let field               x  e = Field   e  x             let projectBySet        xs e = Project e (Left  xs)@@ -348,8 +347,8 @@                     <|> fmap projectBySet        labels                     <|> fmap projectByExpression recordType -            b <- Text.Megaparsec.many (try (do _dot; alternatives))-            return (foldl (\e k -> k e) a b) )+            b <- Text.Megaparsec.many (try (whitespace *> _dot *> whitespace *> alternatives))+            return (foldl' (\e k -> k e) a b) )      primitiveExpression =             noted@@ -365,8 +364,7 @@                     , alternative08                     , alternative37                     , alternative09--                    , builtin <?> "built-in expression"+                    , builtin                     ]                 )             <|> alternative38@@ -392,26 +390,31 @@             alternative04 = (do                 _openBrace -                _ <- optional _comma+                whitespace +                _ <- optional (_comma *> whitespace)+                 a <- recordTypeOrLiteral +                whitespace+                 _closeBrace -                return a ) <?> "record type or literal"+                return a ) <?> "literal"              alternative05 = unionType              alternative06 = listLiteral              alternative07 = do-                _merge+                try (_merge *> nonemptyWhitespace)                 a <- importExpression_+                nonemptyWhitespace                 b <- importExpression_ <?> "second argument to ❰merge❱"                 return (Merge a b Nothing)              alternative08 = do-                _toMap+                try (_toMap *> nonemptyWhitespace)                 a <- importExpression_                 return (ToMap a Nothing) @@ -453,7 +456,9 @@                             ]                     'I' ->                         choice-                            [ IntegerShow      <$ _IntegerShow+                            [ IntegerClamp     <$ _IntegerClamp+                            , IntegerNegate    <$ _IntegerNegate+                            , IntegerShow      <$ _IntegerShow                             , IntegerToDouble  <$ _IntegerToDouble                             , Integer          <$ _Integer                             ]@@ -499,7 +504,9 @@              alternative38 = do                 _openParens+                whitespace                 a <- expression+                whitespace                 _closeParens                 return a @@ -512,9 +519,9 @@                 ]           where             interpolation = do-                _ <- Text.Parser.Char.text "${"+                _ <- text "${"                 e <- completeExpression_-                _ <- Text.Parser.Char.char '}'+                _ <- char '}'                 return (Chunks [(mempty, e)] mempty)              unescapedCharacterFast = do@@ -528,11 +535,11 @@                     ) && c /= '$'              unescapedCharacterSlow = do-                _ <- Text.Parser.Char.char '$'+                _ <- char '$'                 return (Chunks [] "$")              escapedCharacter = do-                _ <- Text.Parser.Char.char '\\'+                _ <- char '\\'                 c <- choice                     [ quotationMark                     , dollarSign@@ -547,53 +554,60 @@                     ]                 return (Chunks [] (Data.Text.singleton c))               where-                quotationMark = Text.Parser.Char.char '"'+                quotationMark = char '"' -                dollarSign = Text.Parser.Char.char '$'+                dollarSign = char '$' -                backSlash = Text.Parser.Char.char '\\'+                backSlash = char '\\' -                forwardSlash = Text.Parser.Char.char '/'+                forwardSlash = char '/' -                backSpace = do _ <- Text.Parser.Char.char 'b'; return '\b'+                backSpace = do _ <- char 'b'; return '\b' -                formFeed = do _ <- Text.Parser.Char.char 'f'; return '\f'+                formFeed = do _ <- char 'f'; return '\f' -                lineFeed = do _ <- Text.Parser.Char.char 'n'; return '\n'+                lineFeed = do _ <- char 'n'; return '\n' -                carriageReturn = do _ <- Text.Parser.Char.char 'r'; return '\r'+                carriageReturn = do _ <- char 'r'; return '\r' -                tab = do _ <- Text.Parser.Char.char 't'; return '\t'+                tab = do _ <- char 't'; return '\t'                  unicode = do-                    _  <- Text.Parser.Char.char 'u';+                    _  <- char 'u';                      let toNumber = Data.List.foldl' (\x y -> x * 16 + y) 0 -                    let fourCharacterEscapeSequence =-                            fmap toNumber (Control.Monad.replicateM 4 hexNumber)+                    let fourCharacterEscapeSequence = do+                            ns <- Control.Monad.replicateM 4 hexNumber+                            +                            let number = toNumber ns +                            Control.Monad.guard (validCodepoint number)+                                <|> fail "Invalid Unicode code point"++                            return number+                     let bracedEscapeSequence = do-                            _  <- Text.Parser.Char.char '{'+                            _  <- char '{'                             ns <- some hexNumber                              let number = toNumber ns -                            Control.Monad.guard (number <= 0x10FFFF && validCodepoint (Char.chr number))+                            Control.Monad.guard (number <= 0x10FFFD && validCodepoint number)                                 <|> fail "Invalid Unicode code point" -                            _  <- Text.Parser.Char.char '}'+                            _  <- char '}' -                            return (toNumber ns)+                            return number                      n <- bracedEscapeSequence <|> fourCharacterEscapeSequence                      return (Char.chr n)      doubleQuotedLiteral = do-            _      <- Text.Parser.Char.char '"'+            _      <- char '"'             chunks <- Text.Megaparsec.many doubleQuotedChunk-            _      <- Text.Parser.Char.char '"'+            _      <- char '"'             return (mconcat chunks)      singleQuoteContinue =@@ -614,19 +628,19 @@                     return ("''" <> b)                  interpolation = do-                    _ <- Text.Parser.Char.text "${"+                    _ <- text "${"                     a <- completeExpression_-                    _ <- Text.Parser.Char.char '}'+                    _ <- char '}'                     b <- singleQuoteContinue                     return (Chunks [(mempty, a)] mempty <> b)                  escapeInterpolation = do-                    _ <- Text.Parser.Char.text "''${"+                    _ <- text "''${"                     b <- singleQuoteContinue                     return ("${" <> b)                  endLiteral = do-                    _ <- Text.Parser.Char.text "''"+                    _ <- text "''"                     return mempty                  unescapedCharacterFast = do@@ -650,25 +664,22 @@                     return (Chunks [] a <> b)                  tab = do-                    _ <- Text.Parser.Char.char '\t'+                    _ <- char '\t' <?> "tab"                     b <- singleQuoteContinue                     return ("\t" <> b)      singleQuoteLiteral = do-            _ <- Text.Parser.Char.text "''"+            _ <- text "''"             _ <- endOfLine             a <- singleQuoteContinue              return (toDoubleQuoted a)           where-            endOfLine =-                    void (Text.Parser.Char.char '\n'  )-                <|> void (Text.Parser.Char.text "\r\n")+            endOfLine = (void (char '\n') <|> void (text "\r\n")) <?> "newline"      textLiteral = (do             literal <- doubleQuotedLiteral <|> singleQuoteLiteral-            whitespace-            return (TextLit literal) ) <?> "text literal"+            return (TextLit literal) ) <?> "literal"      recordTypeOrLiteral =             choice@@ -688,28 +699,70 @@     nonEmptyRecordTypeOrLiteral = do             a <- anyLabel +            whitespace+             let nonEmptyRecordType = do                     _colon++                    nonemptyWhitespace+                     b <- expression++                    whitespace+                     e <- Text.Megaparsec.many (do                         _comma++                        whitespace+                         c <- anyLabel++                        whitespace+                         _colon++                        nonemptyWhitespace+                         d <- expression++                        whitespace+                         return (c, d) )+                     m <- toMap ((a, b) : e)+                     return (Record m)              let nonEmptyRecordLiteral = do                     _equal++                    whitespace+                     b <- expression++                    whitespace+                     e <- Text.Megaparsec.many (do                         _comma++                        whitespace+                         c <- anyLabel++                        whitespace+                         _equal++                        whitespace+                         d <- expression++                        whitespace+                         return (c, d) )+                     m <- toMap ((a, b) : e)+                     return (RecordLit m)              nonEmptyRecordType <|> nonEmptyRecordLiteral@@ -717,48 +770,53 @@     unionType = (do             _openAngle -            _ <- optional _bar+            whitespace +            _ <- optional (_bar *> whitespace)+             let unionTypeEntry = do                     a <- anyLabel-                    b <- optional (do _colon; expression)+                    whitespace+                    b <- optional (_colon *> nonemptyWhitespace *> expression <* whitespace)                     return (a, b) -            kvs <- Text.Megaparsec.sepBy unionTypeEntry _bar+            kvs <- Text.Megaparsec.sepBy unionTypeEntry (_bar *> whitespace)              m <- toMap kvs              _closeAngle -            return (Union m) ) <?> "union type"+            return (Union m) ) <?> "literal"      listLiteral = (do             _openBracket -            _ <- optional _comma+            whitespace -            a <- Text.Megaparsec.sepBy expression _comma+            _ <- optional (_comma *> whitespace) +            a <- Text.Megaparsec.sepBy (expression <* whitespace) (_comma *> whitespace)+             _closeBracket-            return (ListLit Nothing (Data.Sequence.fromList a)) ) <?> "list literal" +            return (ListLit Nothing (Data.Sequence.fromList a)) ) <?> "literal"+ {-| Parse an environment variable import      This corresponds to the @env@ rule from the official grammar -} env :: Parser ImportType env = do-    _ <- Text.Parser.Char.text "env:"+    _ <- text "env:"     a <- (alternative0 <|> alternative1)-    whitespace     return (Env a)   where     alternative0 = bashEnvironmentVariable      alternative1 = do-        _ <- Text.Parser.Char.char '"'+        _ <- char '"'         a <- posixEnvironmentVariable-        _ <- Text.Parser.Char.char '"'+        _ <- char '"'         return a  -- | Parse a local import without trailing whitespace@@ -801,7 +859,6 @@ local :: Parser ImportType local = do     a <- localOnly-    whitespace     return a  {-| Parse an HTTP(S) import@@ -811,9 +868,8 @@ http :: Parser ImportType http = do     url <- httpRaw-    whitespace     headers <- optional (do-        _using+        try (whitespace *> _using *> nonemptyWhitespace)         importExpression import_ )     return (Remote (url { headers })) @@ -845,10 +901,9 @@ -} importHash_ :: Parser Dhall.Crypto.SHA256Digest importHash_ = do-    _ <- Text.Parser.Char.text "sha256:"-    text <- count 64 (satisfy hexdig <?> "hex digit")-    whitespace-    let strictBytes16 = Data.Text.Encoding.encodeUtf8 text+    _ <- 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         Left  string      -> fail string         Right strictBytes -> return (strictBytes :: Data.ByteString.ByteString)@@ -863,7 +918,7 @@ importHashed_ :: Parser ImportHashed importHashed_ = do     importType <- importType_-    hash       <- optional importHash_+    hash       <- optional (try (nonemptyWhitespace *> importHash_))     return (ImportHashed {..})  {-| Parse an `Import`@@ -877,7 +932,8 @@     return (Import {..}) ) <?> "import"   where     alternative = do-      _as+      try (whitespace *> _as *> nonemptyWhitespace)+       (_Text >> pure RawText) <|> (_Location >> pure Location)  -- | Same as @Data.Text.splitOn@, except always returning a `NonEmpty` result
src/Dhall/Parser/Token.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE OverloadedStrings #-}+ -- | 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 (@@ -9,8 +10,9 @@     bashEnvironmentVariable,     posixEnvironmentVariable,     ComponentType(..),+    text,+    char,     file_,-    labelOnly,     label,     anyLabel,     labels,@@ -26,7 +28,6 @@     _if,     _then,     _else,-    _letOnly,     _let,     _in,     _as,@@ -44,6 +45,8 @@     _NaturalToInteger,     _NaturalShow,     _NaturalSubtract,+    _IntegerClamp,+    _IntegerNegate,     _IntegerShow,     _IntegerToDouble,     _DoubleShow,@@ -70,7 +73,6 @@     _Kind,     _Sort,     _Location,-    _equalOnly,     _equal,     _or,     _plus,@@ -91,7 +93,6 @@     _comma,     _openParens,     _closeParens,-    _colonOnly,     _colon,     _at,     _equivalent,@@ -109,10 +110,11 @@ import           Dhall.Parser.Combinators  import Control.Applicative (Alternative(..), optional)+import Data.Bits ((.&.)) import Data.Functor (void) import Data.Semigroup (Semigroup(..)) import Data.Text (Text)-import Dhall.Core+import Dhall.Syntax import Dhall.Set (Set) import Prelude hiding (const, pi) import Text.Parser.Combinators (choice, try, (<?>))@@ -134,12 +136,14 @@  import qualified Text.Parser.Token --- | Returns `True` if the given `Char` is a valid Unicode codepoint-validCodepoint :: Char -> Bool+-- | Returns `True` if the given `Int` is a valid Unicode codepoint+validCodepoint :: Int -> Bool validCodepoint c =-    not (category == Char.Surrogate || category == Char.NotAssigned)+    not (category == Char.Surrogate +      || c .&. 0xFFFE == 0xFFFE +      || c .&. 0xFFFF == 0xFFFF)   where-    category = Char.generalCategory c+    category = Char.generalCategory (Char.chr c)  {-| Parse 0 or more whitespace characters (including comments) @@ -176,8 +180,8 @@  signPrefix :: Num a => Parser (a -> a) signPrefix = (do-    let positive = fmap (\_ -> id    ) (Text.Parser.Char.char '+')-    let negative = fmap (\_ -> negate) (Text.Parser.Char.char '-')+    let positive = fmap (\_ -> id    ) (char '+')+    let negative = fmap (\_ -> negate) (char '-')     positive <|> negative ) <?> "sign"  {-| Parse a `Double` literal@@ -188,7 +192,7 @@ doubleLiteral = (do     sign <- signPrefix <|> pure id     a <- Text.Parser.Token.double-    return (sign a) ) <?> "double literal"+    return (sign a) ) <?> "literal"  {-| Parse a signed @Infinity@ @@ -197,10 +201,10 @@ -} doubleInfinity :: Parser Double doubleInfinity = (do-    let negative = fmap (\_ -> negate) (Text.Parser.Char.char '-')+    let negative = fmap (\_ -> negate) (char '-')     sign <- negative <|> pure id-    a <- Text.Parser.Char.text "Infinity" >> whitespace >> return (1.0/0.0)-    return (sign a) ) <?> "double infinity"+    a <- text "Infinity" >> return (1.0/0.0)+    return (sign a) ) <?> "literal"  {-| Parse an `Integer` literal @@ -210,8 +214,7 @@ integerLiteral = (do     sign <- signPrefix     a <- Text.Megaparsec.Char.Lexer.decimal-    whitespace-    return (sign a) ) <?> "integer literal"+    return (sign a) ) <?> "literal"  {-| Parse a `Natural` literal  @@ -220,8 +223,7 @@ naturalLiteral :: Parser Natural naturalLiteral = (do     a <- Text.Megaparsec.Char.Lexer.decimal-    whitespace-    return a ) <?> "natural literal"+    return a ) <?> "literal"  {-| Parse an identifier (i.e. a variable or built-in) @@ -233,10 +235,11 @@ identifier = do     x <- label -    let indexed = do-            _ <- Text.Parser.Char.char '@'-            n <- Text.Megaparsec.Char.Lexer.decimal+    let indexed = try $ do             whitespace+            _at+            whitespace+            n <- Text.Megaparsec.Char.Lexer.decimal             return n      n <- indexed <|> pure 0@@ -246,7 +249,7 @@ whitespaceChunk =     choice         [ void (Dhall.Parser.Combinators.takeWhile1 predicate)-        , void (Text.Parser.Char.text "\r\n")+        , void (Text.Parser.Char.text "\r\n" <?> "newline")         , lineComment         , blockComment         ] <?> "whitespace"@@ -277,7 +280,7 @@  lineComment :: Parser () lineComment = do-    _ <- Text.Parser.Char.text "--"+    _ <- text "--"      let predicate c = ('\x20' <= c && c <= '\x10FFFF') || c == '\t' @@ -288,12 +291,13 @@     return ()   where     endOfLine =-            void (Text.Parser.Char.char '\n'  )+        (   void (Text.Parser.Char.char '\n'  )         <|> void (Text.Parser.Char.text "\r\n")+        ) <?> "newline"  blockComment :: Parser () blockComment = do-    _ <- Text.Parser.Char.text "{-"+    _ <- text "{-"     blockCommentContinue  blockCommentChunk :: Parser ()@@ -316,12 +320,12 @@       where         predicate c = '\x20' <= c && c <= '\x10FFFF' || c == '\n' || c == '\t' -    endOfLine = void (Text.Parser.Char.text "\r\n")+    endOfLine = void (Text.Parser.Char.text "\r\n" <?> "newline")  blockCommentContinue :: Parser () blockCommentContinue = endOfComment <|> continue   where-    endOfComment = void (Text.Parser.Char.text "-}")+    endOfComment = void (text "-}")      continue = do         blockCommentChunk@@ -331,9 +335,9 @@ simpleLabel allowReserved = try (do     c    <- Text.Parser.Char.satisfy headCharacter     rest <- Dhall.Parser.Combinators.takeWhile tailCharacter-    let text = Data.Text.cons c rest-    Control.Monad.guard (allowReserved || not (Data.HashSet.member text reservedIdentifiers))-    return text )+    let t = Data.Text.cons c rest+    Control.Monad.guard (allowReserved || not (Data.HashSet.member t reservedIdentifiers))+    return t )   where     headCharacter c = alpha c || c == '_' @@ -341,9 +345,9 @@  backtickLabel :: Parser Text backtickLabel = do-    _ <- Text.Parser.Char.char '`'+    _ <- char '`'     t <- takeWhile1 predicate-    _ <- Text.Parser.Char.char '`'+    _ <- char '`'     return t   where     predicate c =@@ -359,6 +363,7 @@ labels :: Parser (Set Text) labels = do     _openBrace+    whitespace     xs <- nonEmptyLabels <|> emptyLabels     _closeBrace     return xs@@ -367,13 +372,10 @@      nonEmptyLabels = do         x  <- anyLabel-        xs <- many (do _ <- _comma; anyLabel)+        whitespace+        xs <- many (do _comma; whitespace; l <- anyLabel; whitespace; return l)         noDuplicates (x : xs) --- | Parse a label without parsing trailing whitespace-labelOnly :: Parser Text-labelOnly = backtickLabel <|> simpleLabel False <?> "label"- {-| Parse a label (e.g. a variable\/field\/alternative name)      Rejects labels that match built-in names (e.g. @Natural/even@)@@ -381,10 +383,7 @@     This corresponds to the @nonreserved-label@ rule in the official grammar -} label :: Parser Text-label = (do-    t <- backtickLabel <|> simpleLabel False-    whitespace-    return t ) <?> "label"+label = backtickLabel <|> simpleLabel False <?> "label"  {-| Same as `label` except that built-in names are allowed @@ -393,7 +392,6 @@ anyLabel :: Parser Text anyLabel = (do     t <- backtickLabel <|> simpleLabel True-    whitespace     return t ) <?> "any label"  {-| Parse a valid Bash environment variable name@@ -422,7 +420,7 @@     escapeCharacter <|> satisfy predicate1   where     escapeCharacter = do-        _ <- Text.Parser.Char.char '\\'+        _ <- char '\\'          c <- Text.Parser.Char.satisfy (`elem` ("\"\\abfnrtv" :: String)) @@ -463,20 +461,20 @@     let pathData =             case componentType of                 FileComponent -> do-                    Text.Megaparsec.takeWhile1P Nothing Dhall.Core.pathCharacter+                    Text.Megaparsec.takeWhile1P Nothing Dhall.Syntax.pathCharacter                 URLComponent -> do                     star pchar      let quotedPathData = do-            _    <- Text.Parser.Char.char '"'-            text <- Text.Megaparsec.takeWhile1P Nothing quotedPathCharacter-            _    <- Text.Parser.Char.char '"'+            _ <- char '"'+            t <- Text.Megaparsec.takeWhile1P Nothing quotedPathCharacter+            _ <- char '"'              case componentType of               FileComponent -> do-                return text+                return t               URLComponent -> do-                return (URI.Encode.encodeText text)+                return (URI.Encode.encodeText t)      quotedPathData <|> pathData @@ -649,20 +647,40 @@ unreserved c =     alphaNum c || c == '-' || c == '.' || c == '_' || c == '~' -reserved :: Data.Text.Text -> Parser ()-reserved x = do _ <- Text.Parser.Char.text x; whitespace+{-| A variation on `Text.Parser.Char.text` that doesn't quote the expected+    in error messages+-}+text :: Data.Text.Text -> Parser Text+text t = Text.Parser.Char.text t <?> Data.Text.unpack t+{-# INLINE text #-} -reservedCharOnly :: Char -> Parser ()-reservedCharOnly c = do _ <- Text.Parser.Char.char c; return ()+{-| A variation on `Text.Parser.Char.char` that doesn't quote the expected+    token in error messages+-}+char :: Char -> Parser Char+char c = Text.Parser.Char.char c <?> [ c ]+{-# INLINE char #-} +reserved :: Data.Text.Text -> Parser ()+reserved x = void (text x)+ reservedChar :: Char -> Parser ()-reservedChar c = do _ <- Text.Parser.Char.char c; whitespace+reservedChar c = void (char c) -keywordOnly :: Data.Text.Text -> Parser ()-keywordOnly x = try (do _ <- Text.Parser.Char.text x; return ())+builtin :: Data.Text.Text -> Parser ()+builtin x = reserved x <?> "built-in"+{-# INLINE builtin #-} +operator :: Data.Text.Text -> Parser ()+operator x = reserved x <?> "operator"+{-# INLINE operator #-}++operatorChar :: Char -> Parser ()+operatorChar x = reservedChar x <?> "operator"+{-# INLINE operatorChar #-}+ keyword :: Data.Text.Text -> Parser ()-keyword x = try (do _ <- Text.Parser.Char.text x; nonemptyWhitespace)+keyword x = try (void (text x)) <?> "keyword"  {-| Parse the @if@ keyword @@ -685,10 +703,6 @@ _else :: Parser () _else = keyword "else" --- | Parse the @let@ keyword without trailing whitespace-_letOnly :: Parser ()-_letOnly = keywordOnly "let"- {-| Parse the @let@ keyword      This corresponds to the @let@ rule from the official grammar@@ -750,256 +764,266 @@     This corresponds to the @None@ rule from the official grammar -} _None :: Parser ()-_None = reserved "None"+_None = builtin "None"  {-| Parse the @Natural/fold@ built-in      This corresponds to the @Natural-fold@ rule from the official grammar -} _NaturalFold :: Parser ()-_NaturalFold = reserved "Natural/fold"+_NaturalFold = builtin "Natural/fold"  {-| Parse the @Natural/build@ built-in      This corresponds to the @Natural-build@ rule from the official grammar -} _NaturalBuild :: Parser ()-_NaturalBuild = reserved "Natural/build"+_NaturalBuild = builtin "Natural/build"  {-| Parse the @Natural/isZero@ built-in      This corresponds to the @Natural-isZero@ rule from the official grammar -} _NaturalIsZero :: Parser ()-_NaturalIsZero = reserved "Natural/isZero"+_NaturalIsZero = builtin "Natural/isZero"  {-| Parse the @Natural/even@ built-in      This corresponds to the @Natural-even@ rule from the official grammar -} _NaturalEven :: Parser ()-_NaturalEven = reserved "Natural/even"+_NaturalEven = builtin "Natural/even"  {-| Parse the @Natural/odd@ built-in      This corresponds to the @Natural-odd@ rule from the official grammar -} _NaturalOdd :: Parser ()-_NaturalOdd = reserved "Natural/odd"+_NaturalOdd = builtin "Natural/odd"  {-| Parse the @Natural/toInteger@ built-in      This corresponds to the @Natural-toInteger@ rule from the official grammar -} _NaturalToInteger :: Parser ()-_NaturalToInteger = reserved "Natural/toInteger"+_NaturalToInteger = builtin "Natural/toInteger"  {-| Parse the @Natural/show@ built-in      This corresponds to the @Natural-show@ rule from the official grammar -} _NaturalShow :: Parser ()-_NaturalShow = reserved "Natural/show"+_NaturalShow = builtin "Natural/show"  {-| Parse the @Natural/subtract@ built-in      This corresponds to the @Natural-subtract@ rule from the official grammar -} _NaturalSubtract :: Parser ()-_NaturalSubtract = reserved "Natural/subtract"+_NaturalSubtract = builtin "Natural/subtract" +{-| Parse the @Integer/clamp@ built-in++    This corresponds to the @Integer-clamp@ rule from the official grammar+-}+_IntegerClamp :: Parser ()+_IntegerClamp = builtin "Integer/clamp"++{-| Parse the @Integer/negate@ built-in++    This corresponds to the @Integer-negate@ rule from the official grammar+-}+_IntegerNegate :: Parser ()+_IntegerNegate = builtin "Integer/negate"+ {-| Parse the @Integer/show@ built-in      This corresponds to the @Integer-show@ rule from the official grammar -} _IntegerShow :: Parser ()-_IntegerShow = reserved "Integer/show"+_IntegerShow = builtin "Integer/show"  {-| Parse the @Integer/toDouble@ built-in      This corresponds to the @Integer-toDouble@ rule from the official grammar -} _IntegerToDouble :: Parser ()-_IntegerToDouble = reserved "Integer/toDouble"+_IntegerToDouble = builtin "Integer/toDouble"  {-| Parse the @Double/show@ built-in      This corresponds to the @Double-show@ rule from the official grammar -} _DoubleShow :: Parser ()-_DoubleShow = reserved "Double/show"+_DoubleShow = builtin "Double/show"  {-| Parse the @List/build@ built-in      This corresponds to the @List-build@ rule from the official grammar -} _ListBuild :: Parser ()-_ListBuild = reserved "List/build"+_ListBuild = builtin "List/build"  {-| Parse the @List/fold@ built-in      This corresponds to the @List-fold@ rule from the official grammar -} _ListFold :: Parser ()-_ListFold = reserved "List/fold"+_ListFold = builtin "List/fold"  {-| Parse the @List/length@ built-in      This corresponds to the @List-length@ rule from the official grammar -} _ListLength :: Parser ()-_ListLength = reserved "List/length"+_ListLength = builtin "List/length"  {-| Parse the @List/head@ built-in      This corresponds to the @List-head@ rule from the official grammar -} _ListHead :: Parser ()-_ListHead = reserved "List/head"+_ListHead = builtin "List/head"  {-| Parse the @List/last@ built-in      This corresponds to the @List-last@ rule from the official grammar -} _ListLast :: Parser ()-_ListLast = reserved "List/last"+_ListLast = builtin "List/last"  {-| Parse the @List/indexed@ built-in      This corresponds to the @List-indexed@ rule from the official grammar -} _ListIndexed :: Parser ()-_ListIndexed = reserved "List/indexed"+_ListIndexed = builtin "List/indexed"  {-| Parse the @List/reverse@ built-in      This corresponds to the @List-reverse@ rule from the official grammar -} _ListReverse :: Parser ()-_ListReverse = reserved "List/reverse"+_ListReverse = builtin "List/reverse"  {-| Parse the @Optional/fold@ built-in      This corresponds to the @Optional-fold@ rule from the official grammar -} _OptionalFold :: Parser ()-_OptionalFold = reserved "Optional/fold"+_OptionalFold = builtin "Optional/fold"  {-| Parse the @Optional/build@ built-in      This corresponds to the @Optional-build@ rule from the official grammar -} _OptionalBuild :: Parser ()-_OptionalBuild = reserved "Optional/build"+_OptionalBuild = builtin "Optional/build"  {-| Parse the @Bool@ built-in      This corresponds to the @Bool@ rule from the official grammar -} _Bool :: Parser ()-_Bool = reserved "Bool"+_Bool = builtin "Bool"  {-| Parse the @Optional@ built-in      This corresponds to the @Optional@ rule from the official grammar -} _Optional :: Parser ()-_Optional = reserved "Optional"+_Optional = builtin "Optional"  {-| Parse the @Natural@ built-in      This corresponds to the @Natural@ rule from the official grammar -} _Natural :: Parser ()-_Natural = reserved "Natural"+_Natural = builtin "Natural"  {-| Parse the @Integer@ built-in      This corresponds to the @Integer@ rule from the official grammar -} _Integer :: Parser ()-_Integer = reserved "Integer"+_Integer = builtin "Integer"  {-| Parse the @Double@ built-in      This corresponds to the @Double@ rule from the official grammar -} _Double :: Parser ()-_Double = reserved "Double"+_Double = builtin "Double"  {-| Parse the @Text@ built-in      This corresponds to the @Text@ rule from the official grammar -} _Text :: Parser ()-_Text = reserved "Text"+_Text = builtin "Text"  {-| Parse the @Text/show@ built-in      This corresponds to the @Text-show@ rule from the official grammar -} _TextShow :: Parser ()-_TextShow = reserved "Text/show"+_TextShow = builtin "Text/show"  {-| Parse the @List@ built-in      This corresponds to the @List@ rule from the official grammar -} _List :: Parser ()-_List = reserved "List"+_List = builtin "List"  {-| Parse the @True@ built-in      This corresponds to the @True@ rule from the official grammar -} _True :: Parser ()-_True = reserved "True"+_True = builtin "True"  {-| Parse the @False@ built-in      This corresponds to the @False@ rule from the official grammar -} _False :: Parser ()-_False = reserved "False"+_False = builtin "False"  {-| Parse a @NaN@ literal      This corresponds to the @NaN@ rule from the official grammar -} _NaN :: Parser ()-_NaN = reserved "NaN"+_NaN = builtin "NaN"  {-| Parse the @Type@ built-in      This corresponds to the @Type@ rule from the official grammar -} _Type :: Parser ()-_Type = reserved "Type"+_Type = builtin "Type"  {-| Parse the @Kind@ built-in      This corresponds to the @Kind@ rule from the official grammar -} _Kind :: Parser ()-_Kind = reserved "Kind"+_Kind = builtin "Kind"  {-| Parse the @Sort@ built-in      This corresponds to the @Sort@ rule from the official grammar -} _Sort :: Parser ()-_Sort = reserved "Sort"+_Sort = builtin "Sort"  {-| Parse the @Location@ keyword      This corresponds to the @Location@ rule from the official grammar -} _Location :: Parser ()-_Location = reserved "Location"---- | Parse the @=@ symbol without trailing whitespace-_equalOnly :: Parser ()-_equalOnly = reservedCharOnly '='+_Location = builtin "Location"  -- | Parse the @=@ symbol _equal :: Parser ()@@ -1007,39 +1031,39 @@  -- | Parse the @||@ symbol _or :: Parser ()-_or = reserved "||"+_or = operator "||"  -- | Parse the @+@ symbol _plus :: Parser ()-_plus = reservedChar '+'+_plus = operatorChar '+'  -- | Parse the @++@ symbol _textAppend :: Parser ()-_textAppend = reserved "++"+_textAppend = operator "++"  -- | Parse the @#@ symbol _listAppend :: Parser ()-_listAppend = reservedChar '#'+_listAppend = operatorChar '#'  -- | Parse the @&&@ symbol _and :: Parser ()-_and = reserved "&&"+_and = operator "&&"  -- | Parse the @*@ symbol _times :: Parser ()-_times = reservedChar '*'+_times = operatorChar '*'  -- | Parse the @==@ symbol _doubleEqual :: Parser ()-_doubleEqual = reserved "=="+_doubleEqual = operator "=="  -- | Parse the @!=@ symbol _notEqual :: Parser ()-_notEqual = reserved "!="+_notEqual = operator "!="  -- | Parse the @.@ symbol _dot :: Parser ()-_dot = reservedChar '.'+_dot = operatorChar '.'  -- | Parse the @{@ symbol _openBrace :: Parser ()@@ -1071,7 +1095,7 @@  -- | Parse the @,@ symbol _comma :: Parser ()-_comma = reservedChar ','+_comma = reservedChar ',' <?> "\',\'"  -- | Parse the @(@ symbol _openParens :: Parser ()@@ -1081,23 +1105,17 @@ _closeParens :: Parser () _closeParens = reservedChar ')' --- | Parse the @:@ symbol without trailing whitespace-_colonOnly :: Parser ()-_colonOnly = reservedCharOnly ':'- -- | Parse the @:@ symbol _colon :: Parser () _colon = reservedChar ':'  -- | Parse the @\@@ symbol _at :: Parser ()-_at = reservedChar '@'+_at = reservedChar '@' <?> "\"@\""  -- | Parse the equivalence symbol (@===@ or @≡@) _equivalent :: Parser ()-_equivalent = do-    void (Text.Parser.Char.char '≡' <?> "\"≡\"") <|> void (Text.Parser.Char.text "===")-    whitespace+_equivalent = (void (char '≡' <?> "\"≡\"") <|> void (text "===")) <?> "operator"  -- | Parse the @missing@ keyword _missing :: Parser ()@@ -1105,31 +1123,23 @@  -- | Parse the @?@ symbol _importAlt :: Parser ()-_importAlt = reservedChar '?'+_importAlt = operatorChar '?'  -- | Parse the record combine operator (@/\\@ or @∧@) _combine :: Parser ()-_combine = do-    void (Text.Parser.Char.char '∧' <?> "\"∧\"") <|> void (Text.Parser.Char.text "/\\")-    whitespace+_combine = (void (char '∧' <?> "\"∧\"") <|> void (text "/\\")) <?> "operator"  -- | Parse the record type combine operator (@//\\\\@ or @⩓@) _combineTypes :: Parser ()-_combineTypes = do-    void (Text.Parser.Char.char '⩓' <?> "\"⩓\"") <|> void (Text.Parser.Char.text "//\\\\")-    whitespace+_combineTypes = (void (char '⩓' <?> "\"⩓\"") <|> void (text "//\\\\")) <?> "operator"  -- | Parse the record \"prefer\" operator (@//@ or @⫽@) _prefer :: Parser ()-_prefer = do-    void (Text.Parser.Char.char '⫽' <?> "\"⫽\"") <|> void (Text.Parser.Char.text "//")-    whitespace+_prefer = (void (char '⫽' <?> "\"⫽\"") <|> void (text "//")) <?> "operator"  -- | Parse a lambda (@\\@ or @λ@) _lambda :: Parser ()-_lambda = do-    _ <- Text.Parser.Char.satisfy predicate-    whitespace+_lambda = void (Text.Parser.Char.satisfy predicate) <?> "\\"   where     predicate 'λ'  = True     predicate '\\' = True@@ -1137,16 +1147,12 @@  -- | Parse a forall (@forall@ or @∀@) _forall :: Parser ()-_forall = do-    void (Text.Parser.Char.char '∀' <?> "\"∀\"") <|> void (Text.Parser.Char.text "forall")-    whitespace+_forall = (void (char '∀' <?> "\"∀\"") <|> void (text "forall")) <?> "forall"  -- | Parse a right arrow (@->@ or @→@) _arrow :: Parser ()-_arrow = do-    void (Text.Parser.Char.char '→' <?> "\"→\"") <|> void (Text.Parser.Char.text "->")-    whitespace+_arrow = (void (char '→' <?> "\"→\"") <|> void (text "->")) <?> "->"  -- | Parse a double colon (@::@) _doubleColon :: Parser ()-_doubleColon = reserved "::"+_doubleColon = operator "::"
src/Dhall/Pretty.hs view
@@ -10,14 +10,8 @@     , CharacterSet(..)     , prettyCharacterSet -    , layoutOpts+    , Dhall.Pretty.Internal.layout+    , Dhall.Pretty.Internal.layoutOpts     ) where  import Dhall.Pretty.Internal-import qualified Data.Text.Prettyprint.Doc as Pretty---- | Default layout options-layoutOpts :: Pretty.LayoutOptions-layoutOpts =-    Pretty.defaultLayoutOptions-        { Pretty.layoutPageWidth = Pretty.AvailablePerLine 80 1.0 }
src/Dhall/Pretty/Internal.hs view
@@ -21,6 +21,7 @@     , prettyVar     , pretty_     , escapeText_+    , prettyEnvironmentVariable      , prettyConst     , prettyLabel@@ -32,6 +33,8 @@     , prettyDouble     , prettyToStrictText     , prettyToString+    , layout+    , layoutOpts      , docToStrictText @@ -96,6 +99,7 @@   | Literal     -- ^ Literals such as integers and strings   | Builtin     -- ^ Builtin types and values   | Operator    -- ^ Operators+  deriving Show  {-| Convert annotations to their corresponding color for syntax highlighting     purposes@@ -109,7 +113,7 @@ annToAnsiStyle Operator = Terminal.bold <> Terminal.colorDull Terminal.Green  -- | This type determines whether to render code as `ASCII` or `Unicode`-data CharacterSet = ASCII | Unicode+data CharacterSet = ASCII | Unicode deriving Show  -- | Pretty print an expression prettyExpr :: Pretty a => Expr s a -> Doc Ann@@ -407,11 +411,14 @@ digit :: Char -> Bool digit c = '\x30' <= c && c <= '\x39' +alphaNum :: Char -> Bool+alphaNum c = alpha c || digit c+ headCharacter :: Char -> Bool headCharacter c = alpha c || c == '_'  tailCharacter :: Char -> Bool-tailCharacter c = alpha c || digit c || c == '_' || c == '-' || c == '/'+tailCharacter c = alphaNum c || c == '_' || c == '-' || c == '/'  prettyLabelShared :: Bool -> Text -> Doc Ann prettyLabelShared allowReserved a = label doc@@ -457,6 +464,17 @@ prettyVar (V x 0) = label (Pretty.unAnnotate (prettyLabel x)) prettyVar (V x n) = label (Pretty.unAnnotate (prettyLabel x <> "@" <> prettyInt n)) +prettyEnvironmentVariable :: Text -> Doc ann+prettyEnvironmentVariable t+  | validBashEnvVar t = Pretty.pretty t+  | otherwise         = Pretty.pretty ("\"" <> escapeText_ t <> "\"")+  where+    validBashEnvVar v = case Text.uncons v of+        Nothing      -> False+        Just (c, v') ->+                (alpha c || c == '_')+            &&  Text.all (\c' -> alphaNum c' || c' == '_') v'+ {-  There is a close correspondence between the pretty-printers in 'prettyCharacterSet'     and the sub-parsers in 'Dhall.Parser.Expression.parsers'.  Most pretty-printers are     named after the corresponding parser and the relationship between pretty-printers@@ -954,6 +972,10 @@         builtin "Natural/subtract"     prettyPrimitiveExpression Integer =         builtin "Integer"+    prettyPrimitiveExpression IntegerClamp =+        builtin "Integer/clamp"+    prettyPrimitiveExpression IntegerNegate =+        builtin "Integer/negate"     prettyPrimitiveExpression IntegerShow =         builtin "Integer/show"     prettyPrimitiveExpression IntegerToDouble =@@ -1066,37 +1088,48 @@         angles . map prettyAlternative . Dhall.Map.toList      prettyChunks :: Pretty a => Chunks Src a -> Doc Ann-    prettyChunks (Chunks a b) =-        if any (\(builder, _) -> hasNewLine builder) a || hasNewLine b-        then Pretty.flatAlt long short-        else short+    prettyChunks chunks@(Chunks a b)+        | anyText (== '\n') =+            if not (null a) || anyText (/= '\n')+            then long+            else Pretty.group (Pretty.flatAlt long short)+        | otherwise =+            short       where         long =             Pretty.align-            (   literal ("''" <> Pretty.hardline)+            (   literal "''" <> Pretty.hardline             <>  Pretty.align-                (foldMap prettyMultilineChunk a <> prettyMultilineBuilder b)+                (foldMap prettyMultilineChunk a' <> prettyMultilineText b')             <>  literal "''"             )+          where+            Chunks a' b' = multilineChunks chunks          short =             literal "\"" <> foldMap prettyChunk a <> literal (prettyText b <> "\"") -        hasNewLine = Text.any (== '\n')+        anyText predicate = any (\(text, _) -> Text.any predicate text) a || Text.any predicate b          prettyMultilineChunk (c, d) =-                prettyMultilineBuilder c+                prettyMultilineText c             <>  dollar             <>  lbrace             <>  prettyExpression d             <>  rbrace -        prettyMultilineBuilder builder = literal (mconcat docs)+        prettyMultilineText text = mconcat docs           where-            lazyLines = Text.splitOn "\n" (escapeSingleQuotedText builder)+            lines_ = Text.splitOn "\n" (escapeSingleQuotedText text) +            -- Annotate only non-empty lines so trailing whitespace can be+            -- removed on empty ones.+            prettyLine line =+                (if Text.null line then id else literal)+                    (Pretty.pretty line)+             docs =-                Data.List.intersperse Pretty.hardline (fmap Pretty.pretty lazyLines)+                Data.List.intersperse Pretty.hardline (map prettyLine lines_)          prettyChunk (c, d) =                 prettyText c@@ -1106,20 +1139,125 @@          prettyText t = literal (Pretty.pretty (escapeText_ t)) ++-- | Prepare 'Chunks' for multi-line formatting by escaping problematic+-- character sequences via string interpolations+--+-- >>> multilineChunks (Chunks [] "\n \tx")+-- Chunks [("\n",TextLit (Chunks [] " \t"))] "x"+-- >>> multilineChunks (Chunks [] "\n\NUL\b\f\t")+-- Chunks [("\n",TextLit (Chunks [] "\NUL\b\f"))] "\t"+multilineChunks :: Chunks s a -> Chunks s a+multilineChunks =+     escapeTrailingSingleQuote+   . escapeControlCharacters+   . escapeLastLineLeadingWhitespace++-- | Escape leading whitespace on the last line by moving it into a string+-- interpolation+--+-- This ensures that the parser can find the correct indentation level, no matter+-- what the other lines contain.-+--+-- >>> escapeLastLineLeadingWhitespace (Chunks [] "\n \tx")+-- Chunks [("\n",TextLit (Chunks [] " \t"))] "x"+-- >>> escapeLastLineLeadingWhitespace (Chunks [("\n",Var (V "x" 0))] " ")+-- Chunks [("\n",Var (V "x" 0))] " "+-- >>> escapeLastLineLeadingWhitespace (Chunks [("\n ",Var (V "x" 0))] "")+-- Chunks [("\n",TextLit (Chunks [] " ")),("",Var (V "x" 0))] ""+-- >>> escapeLastLineLeadingWhitespace (Chunks [("\n ",Var (V "x" 0))] "\n")+-- Chunks [("\n ",Var (V "x" 0))] "\n"+--+-- We assume that there's at least one newline and may therefore ignore leading+-- whitespace on the first line:+--+-- >>> escapeLastLineLeadingWhitespace (Chunks [] " ")+-- Chunks [] " "+escapeLastLineLeadingWhitespace :: Chunks s a -> Chunks s a+escapeLastLineLeadingWhitespace (Chunks as0 b0) =+    case escape1 b0 of+        Nothing             -> Chunks (escapeChunks as0) b0+        Just (Chunks cs b1) -> Chunks (as0 ++ cs) b1+  where+    -- Nothing: No newline found+    -- Just chunks: Newline was found!+    escape1 :: Text -> Maybe (Chunks s a)+    escape1 t = case Text.breakOnEnd "\n" t of+        ("", _) -> Nothing+        (a , b) -> Just $ case Text.span predicate b of+            ("", _) -> Chunks [] t+            (c , d) -> Chunks [(a, TextLit (Chunks [] c))] d++    predicate c = c == ' ' || c == '\t'++    escapeChunks = snd . foldr f (NotDone, [])++    f chunk  (Done   , chunks) = (Done, chunk : chunks)+    f (t, e) (NotDone, chunks) = case escape1 t of+        Nothing            -> (NotDone, (t, e) : chunks)+        Just (Chunks as b) -> (Done, as ++ (b, e) : chunks)++data Done = NotDone | Done++-- | Escape control characters by moving them into string interpolations+--+-- >>> 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+  where+    as1 = foldr f (map toChunk bs) as0++    (bs, b1) = splitOnPredicate predicate b0++    f (t0, e) chunks = map toChunk ts1 ++ (t1, e) : chunks+      where+        (ts1, t1) = splitOnPredicate predicate t0++    predicate c = Data.Char.isControl c && c /= ' ' && c /= '\t' && c /= '\n'++    toChunk (t0, t1) = (t0, TextLit (Chunks [] t1))++-- | Split `Text` on a predicate, preserving all parts of the original string.+--+-- >>> splitOnPredicate (== 'x') ""+-- ([],"")+-- >>> splitOnPredicate (== 'x') " xx "+-- ([(" ","xx")]," ")+-- >>> splitOnPredicate (== 'x') "xx"+-- ([("","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)++-- | Escape a trailing single quote by moving it into a string interpolation+--+-- Otherwise the multiline-string would end with @'''@, which would be parsed+-- as an escaped @''@.+--+-- >>> escapeTrailingSingleQuote (Chunks [] "\n'")+-- Chunks [("\n",TextLit (Chunks [] "'"))] ""+escapeTrailingSingleQuote :: Chunks s a -> Chunks s a+escapeTrailingSingleQuote chunks@(Chunks as b) =+    case Text.unsnoc b of+        Just (b', '\'') -> Chunks (as ++ [(b', TextLit (Chunks [] "'"))]) ""+        _               -> chunks+ -- | Pretty-print a value pretty_ :: Pretty a => a -> Text-pretty_ = Pretty.renderStrict . Pretty.layoutPretty options . Pretty.pretty-  where-   options = Pretty.LayoutOptions { Pretty.layoutPageWidth = Pretty.Unbounded }+pretty_ = prettyToStrictText  -- | Escape a `Text` literal using Dhall's escaping rules for single-quoted --   @Text@ escapeSingleQuotedText :: Text -> Text-escapeSingleQuotedText inputBuilder = outputBuilder+escapeSingleQuotedText inputText = outputText   where-    outputText = substitute "${" "''${" (substitute "''" "'''" inputBuilder)--    outputBuilder = outputText+    outputText = substitute "${" "''${" (substitute "''" "'''" inputText)      substitute before after = Text.intercalate after . Text.splitOn before @@ -1160,14 +1298,30 @@  prettyToString :: Pretty a => a -> String prettyToString =-    Pretty.renderString . Pretty.layoutPretty options . Pretty.pretty-  where-   options = Pretty.LayoutOptions { Pretty.layoutPageWidth = Pretty.Unbounded }+    Pretty.renderString . layout . Pretty.pretty  docToStrictText :: Doc ann -> Text.Text-docToStrictText = Pretty.renderStrict . Pretty.layoutPretty options-  where-   options = Pretty.LayoutOptions { Pretty.layoutPageWidth = Pretty.Unbounded }+docToStrictText = Pretty.renderStrict . layout  prettyToStrictText :: Pretty a => a -> Text.Text prettyToStrictText = docToStrictText . Pretty.pretty++-- | Layout using 'layoutOpts'+--+-- Tries hard to fit the document into 80 columns.+--+-- This also removes trailing space characters (@' '@) /unless/+-- they are enclosed in an annotation.+layout :: Pretty.Doc ann -> Pretty.SimpleDocStream ann+layout = Pretty.removeTrailingWhitespace . Pretty.layoutSmart layoutOpts++-- | Default layout options+layoutOpts :: Pretty.LayoutOptions+layoutOpts =+    Pretty.defaultLayoutOptions+        { Pretty.layoutPageWidth = Pretty.AvailablePerLine 80 1.0 }+++{- $setup+>>> import Test.QuickCheck (Fun(..))+-}
src/Dhall/Pretty/Internal.hs-boot view
@@ -1,5 +1,6 @@ module Dhall.Pretty.Internal where +import Data.Text (Text) import Data.Text.Prettyprint.Doc (Pretty, Doc)  import {-# SOURCE #-} Dhall.Syntax@@ -11,3 +12,5 @@ prettyConst :: Const -> Doc Ann  prettyExpr :: Pretty a => Expr s a -> Doc Ann++prettyEnvironmentVariable :: Text -> Doc ann
src/Dhall/Repl.hs view
@@ -25,6 +25,7 @@ import Data.Void (Void) import Dhall.Context (Context) import Dhall.Import (hashExpressionToCode)+import Dhall.Parser (Parser(..)) import Dhall.Src (Src) import Dhall.Pretty (CharacterSet(..)) import System.Console.Haskeline (Interrupt(..))@@ -43,18 +44,21 @@ import qualified Dhall.Context import qualified Dhall.Core import qualified Dhall.Core as Dhall ( Var(V), Expr, normalize )+import qualified Dhall.Parser.Token                      as Parser.Token import qualified Dhall.Pretty+import qualified Dhall.Pretty.Internal 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.TypeCheck as Dhall-import qualified Dhall.Version as Meta+import qualified Dhall.Import                            as Dhall+import qualified Dhall.Map                               as Map+import qualified Dhall.Parser                            as Dhall+import qualified Dhall.TypeCheck                         as Dhall+import qualified Dhall.Version                           as Meta import qualified System.Console.ANSI-import qualified System.Console.Haskeline.Completion as Haskeline+import qualified System.Console.Haskeline.Completion     as Haskeline import qualified System.Console.Haskeline.MonadException as Haskeline-import qualified System.Console.Repline as Repline+import qualified System.Console.Repline                  as Repline import qualified System.IO+import qualified Text.Megaparsec                         as Megaparsec  type Repl = Repline.HaskelineT (State.StateT Env IO) @@ -212,23 +216,19 @@  addBinding :: ( MonadFail m, MonadIO m, MonadState Env m ) => [String] -> m () addBinding (k : "=" : srcs) = do-  let-    varName =-      Text.pack k+  varName <- case Megaparsec.parse (unParser Parser.Token.label) "(stdin)" (Text.pack k) of+      Left   _      -> Fail.fail "Invalid variable name"+      Right varName -> return varName -  loaded <--    parseAndLoad ( unwords srcs )+  loaded <- parseAndLoad ( unwords srcs ) -  t <--    typeCheck loaded+  t <- typeCheck loaded -  expr <--    normalize loaded+  expr <- normalize loaded    modify     ( \e ->-        e-          { envBindings =+        e { envBindings =               Dhall.Context.insert                 varName                 Binding { bindingType = t, bindingExpr = expr }@@ -351,7 +351,11 @@       handler handle =           State.evalStateT             (forM_ bindings $ \(name, expr) -> do-              liftIO (System.IO.hPutStr handle $ ":let " <> Text.unpack name <> " = ")+              let doc = Dhall.Pretty.Internal.prettyLabel name++              let label = Dhall.Pretty.Internal.docToStrictText doc++              liftIO (System.IO.hPutStr handle $ ":let " <> Text.unpack label <> " = ")               outputWithoutSpacing expr)             (env { outputHandle = Just handle }) @@ -608,9 +612,7 @@   case outputHandle of     Nothing     -> pure ()     Just handle -> do-      let stream =-              Pretty.layoutSmart Dhall.Pretty.layoutOpts-                  (Dhall.Pretty.prettyCharacterSet characterSet expr)+      let stream = Dhall.Pretty.layout (Dhall.Pretty.prettyCharacterSet characterSet expr)        supportsANSI <- liftIO (System.Console.ANSI.hSupportsANSI handle)       let ansiStream =
src/Dhall/Set.hs view
@@ -10,6 +10,7 @@ module Dhall.Set (       Set(..)     , toList+    , toAscList     , toSet     , toSeq     , fromList@@ -20,6 +21,7 @@     , sort     , isSorted     , null+    , size     ) where  import Prelude hiding (null)@@ -57,6 +59,15 @@     foldMap f (Set _ x) = foldMap f x     {-# INLINABLE foldMap #-} +    toList = Dhall.Set.toList+    {-# INLINABLE toList #-}++    null = Dhall.Set.null+    {-# INLINABLE null #-}++    length = Dhall.Set.size+    {-# INLINABLE length #-}+ -- | Convert to an unordered @"Data.Set".`Data.Set.Set`@ toSet :: Set a -> Data.Set.Set a toSet (Set s _) = s@@ -67,8 +78,12 @@  -- | Convert a `Set` to a list, preserving the original order of the elements toList :: Set a -> [a]-toList = Data.Foldable.toList+toList (Set _ xs) = Data.Foldable.toList xs +-- | Convert a `Set` to a list of ascending elements+toAscList :: Set a -> [a]+toAscList (Set s _) = Data.Set.toAscList s+ -- | Convert a list to a `Set`, remembering the element order fromList :: Ord a => [a] -> Set a fromList = foldl' (flip append) empty@@ -103,7 +118,7 @@ True -} sort :: Ord a => Set a -> Set a-sort (Set s xs) = Set s (Data.Sequence.sort xs)+sort (Set s _) = Set s (Data.Sequence.fromList (Data.Set.toList s))  {-| >>> isSorted (fromList [2, 1])@@ -122,3 +137,10 @@ -} null :: Set a -> Bool null (Set s _) = Data.Set.null s++{-|+>>> size (fromList [1])+1+-}+size :: Set a -> Int+size (Set s _) = Data.Set.size s
src/Dhall/Syntax.hs view
@@ -211,7 +211,7 @@ -- -- This instance is also consistent with with the binary encoding of Dhall @Double@s: ----- >>> toBytes n = Codec.Serialise.serialise (Dhall.Binary.encode (n :: DhallDouble))+-- >>> toBytes n = Dhall.Binary.encodeExpression (DoubleLit n :: Expr Void Import) -- -- prop> \a b -> (a == b) == (toBytes a == toBytes b) instance Eq DhallDouble where@@ -338,6 +338,10 @@     | Integer     -- | > IntegerLit n                             ~  ±n     | IntegerLit Integer+    -- | IntegerClamp                               ~  Integer/clamp+    | IntegerClamp+    -- | IntegerNegate                              ~  Integer/negate+    | IntegerNegate     -- | > IntegerShow                              ~  Integer/show     | IntegerShow     -- | > IntegerToDouble                          ~  Integer/toDouble@@ -486,6 +490,8 @@   fmap f (NaturalTimes e1 e2) = NaturalTimes (fmap f e1) (fmap f e2)   fmap _ Integer = Integer   fmap _ (IntegerLit i) = IntegerLit i+  fmap _ IntegerClamp = IntegerClamp+  fmap _ IntegerNegate = IntegerNegate   fmap _ IntegerShow = IntegerShow   fmap _ IntegerToDouble = IntegerToDouble   fmap _ Double = Double@@ -569,6 +575,8 @@     NaturalTimes a b     >>= k = NaturalTimes (a >>= k) (b >>= k)     Integer              >>= _ = Integer     IntegerLit a         >>= _ = IntegerLit a+    IntegerClamp         >>= _ = IntegerClamp+    IntegerNegate        >>= _ = IntegerNegate     IntegerShow          >>= _ = IntegerShow     IntegerToDouble      >>= _ = IntegerToDouble     Double               >>= _ = Double@@ -639,6 +647,8 @@     first k (NaturalTimes a b    ) = NaturalTimes (first k a) (first k b)     first _  Integer               = Integer     first _ (IntegerLit a        ) = IntegerLit a+    first _  IntegerClamp          = IntegerClamp+    first _  IntegerNegate         = IntegerNegate     first _  IntegerShow           = IntegerShow     first _  IntegerToDouble       = IntegerToDouble     first _  Double                = Double@@ -769,6 +779,8 @@ subExpressions f (NaturalTimes a b) = NaturalTimes <$> f a <*> f b subExpressions _ Integer = pure Integer subExpressions _ (IntegerLit n) = pure (IntegerLit n)+subExpressions _ IntegerClamp = pure IntegerClamp+subExpressions _ IntegerNegate = pure IntegerNegate subExpressions _ IntegerShow = pure IntegerShow subExpressions _ IntegerToDouble = pure IntegerToDouble subExpressions _ Double = pure Double@@ -977,7 +989,7 @@      pretty (Remote url) = Pretty.pretty url -    pretty (Env env) = "env:" <> Pretty.pretty env+    pretty (Env env) = "env:" <> prettyEnvironmentVariable env      pretty Missing = "missing" @@ -1074,6 +1086,8 @@ denote (NaturalTimes a b    ) = NaturalTimes (denote a) (denote b) denote  Integer               = Integer denote (IntegerLit a        ) = IntegerLit a+denote  IntegerClamp          = IntegerClamp+denote  IntegerNegate         = IntegerNegate denote  IntegerShow           = IntegerShow denote  IntegerToDouble       = IntegerToDouble denote  Double                = Double@@ -1132,23 +1146,24 @@ reservedIdentifiers :: HashSet Text reservedIdentifiers =     Data.HashSet.fromList-        [ "let"-        , "in"-        , "Type"-        , "Kind"-        , "Sort"-        , "forall"-        , "Bool"-        , "True"-        , "False"-        , "merge"-        , "toMap"-        , "if"+        [ -- Keywords according to the `keyword` rule in the grammar+          "if"         , "then"         , "else"-        , "as"+        , "let"+        , "in"         , "using"-        , "Natural"+        , "missing"+        , "as"+        , "Infinity"+        , "NaN"+        , "merge"+        , "Some"+        , "toMap"+        , "assert"+        , "forall"++          -- Builtins according to the `builtin` rule in the grammar         , "Natural/fold"         , "Natural/build"         , "Natural/isZero"@@ -1158,13 +1173,13 @@         , "Natural/show"         , "Natural/subtract"         , "Integer"+        , "Integer/clamp"+        , "Integer/negate"         , "Integer/show"         , "Integer/toDouble"-        , "Double"+        , "Integer/show"+        , "Natural/subtract"         , "Double/show"-        , "Text"-        , "Text/show"-        , "List"         , "List/build"         , "List/fold"         , "List/length"@@ -1172,11 +1187,20 @@         , "List/last"         , "List/indexed"         , "List/reverse"+        , "Optional/fold"+        , "Optional/build"+        , "Text/show"+        , "Bool"+        , "True"+        , "False"         , "Optional"-        , "Some"         , "None"-        , "Optional/build"-        , "Optional/fold"-        , "NaN"-        , "Infinity"+        , "Natural"+        , "Integer"+        , "Double"+        , "Text"+        , "List"+        , "Type"+        , "Kind"+        , "Sort"         ]
src/Dhall/Tags.hs view
@@ -9,14 +9,14 @@     ) where  import Control.Exception (handle, SomeException(..))-import Data.List (isSuffixOf)+import Data.List (isSuffixOf, foldl') import Data.Maybe (fromMaybe) import Data.Semigroup (Semigroup(..)) import Dhall.Map (foldMapWithKey) import Data.Text (Text) import Data.Text.Encoding (encodeUtf8) import Dhall.Util (Input(..))-import Dhall.Core (Expr(..), Binding(..))+import Dhall.Syntax (Expr(..), Binding(..)) import Dhall.Src (Src(srcStart)) import Dhall.Parser (exprFromText) import System.FilePath ((</>), takeFileName)@@ -144,7 +144,7 @@           --   In example above, first line is 15 bytes long and '\n', mls contain:           --   (1, (16, "let foo = "bar"")           --   That allow us to get byte offset easier.-          mls = M.fromList . fst . foldl processLine ([], 0) . zip [1..] $ T.lines t+          mls = M.fromList . fst . foldl' processLine ([], 0) . zip [1..] $ T.lines t            {-| processLine is a worker for `foldl` that generates the list of lines with               byte offsets from the start of the first line from a list of lines
src/Dhall/Tutorial.hs view
@@ -1498,7 +1498,7 @@ -- We'll use this trick to test changes to the protected import in the following -- examples. ----- Now, supose you add a comment to the @./bar@ file:+-- Now, suppose you add a comment to the @./bar@ file: -- -- > $ cat ./bar -- > -- This comment does not change the hash
src/Dhall/TypeCheck.hs view
@@ -37,12 +37,11 @@ import Data.Text.Prettyprint.Doc (Doc, Pretty(..)) import Data.Typeable (Typeable) import Data.Void (Void, absurd)-import Dhall.Binary (ToTerm(..)) import Dhall.Context (Context)-import Dhall.Core (Binding(..), Const(..), Chunks(..), Expr(..), Var(..))+import Dhall.Syntax (Binding(..), Const(..), Chunks(..), Expr(..), Var(..)) import Dhall.Eval     (Environment(..), Names(..), Val(..), (~>))-import Dhall.Pretty (Ann, layoutOpts)+import Dhall.Pretty (Ann) import Dhall.Src (Src) import Lens.Family (over) @@ -60,6 +59,7 @@ import qualified Dhall.Eval                              as Eval import qualified Dhall.Map import qualified Dhall.Set+import qualified Dhall.Pretty import qualified Dhall.Pretty.Internal import qualified Dhall.Util import qualified Lens.Family@@ -510,6 +510,12 @@         IntegerLit _ -> do             return VInteger +        IntegerClamp -> do+            return (VInteger ~> VNatural)++        IntegerNegate -> do+            return (VInteger ~> VInteger)+         IntegerShow -> do             return (VInteger ~> VText) @@ -588,7 +594,7 @@                                     -- Carefully note that we don't use `die`                                     -- here so that the source span is narrowed                                     -- to just the offending element-                                    let err = MismatchedListElements i _T₀'' t₁ _T₁''+                                    let err = MismatchedListElements (i+1) _T₀'' t₁ _T₁''                                      let context = ctxToContext ctx @@ -678,7 +684,7 @@                             VList a                         ~>  VList                                 (VRecord-                                    (Dhall.Map.fromList+                                    (Dhall.Map.unorderedFromList                                         [ ("index", VNatural)                                         , ("value", a       )                                         ]@@ -897,8 +903,18 @@             return (VRecord (Dhall.Map.union xRs' xLs'))          RecordCompletion l r -> do-            loop ctx (Annot (Prefer (Field l "default") r) (Field l "Type"))+            _L' <- loop ctx l +            case _L' of+                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 (Field l "default") r) (Field l "Type"))+                _ -> die (CompletionSchemaMustBeARecord l (quote names _L'))+         Merge t u mT₁ -> do             _T' <- loop ctx t @@ -934,7 +950,8 @@              if Data.Set.null diffU                 then return ()-                else die (MissingHandler diffU)+                else let (exemplar,rest) = Data.Set.deleteFindMin diffU+                     in die (MissingHandler exemplar rest)              let match _y _T₀' Nothing =                     return _T₀'@@ -1067,7 +1084,7 @@             let mapType _T' =                     VList                         (VRecord-                            (Dhall.Map.fromList+                            (Dhall.Map.unorderedFromList                                 [("mapKey", VText), ("mapValue", _T')]                             )                         )@@ -1133,9 +1150,9 @@                                 Just _T' -> return (x, _T')                                 Nothing  -> die (MissingField x _E'') -                    let adapt = VRecord . Dhall.Map.fromList+                    let adapt = VRecord . Dhall.Map.unorderedFromList -                    fmap adapt (traverse process (Dhall.Set.toList (Dhall.Set.sort xs)))+                    fmap adapt (traverse process (Dhall.Set.toAscList xs))                  _ -> do                     let text =@@ -1284,6 +1301,8 @@     | AlternativeAnnotationMismatch Text (Expr s a) Const Text (Expr s a) Const     | ListAppendMismatch (Expr s a) (Expr s a)     | MustCombineARecord Char (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)     | FieldCollision Text@@ -1296,7 +1315,7 @@     | MapTypeMismatch (Expr s a) (Expr s a)     | MissingToMapType     | UnusedHandler (Set Text)-    | MissingHandler (Set Text)+    | MissingHandler Text (Set Text)     | 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)@@ -1324,13 +1343,13 @@     | CantMultiply (Expr s a) (Expr s a)     deriving (Show) -shortTypeMessage :: (Eq a, Pretty a, ToTerm a) => TypeMessage s a -> Doc Ann+shortTypeMessage :: (Eq a, Pretty a) => TypeMessage s a -> Doc Ann shortTypeMessage msg =     "\ESC[1;31mError\ESC[0m: " <> short <> "\n"   where     ErrorMessages {..} = prettyTypeMessage msg -longTypeMessage :: (Eq a, Pretty a, ToTerm a) => TypeMessage s a -> Doc Ann+longTypeMessage :: (Eq a, Pretty a) => TypeMessage s a -> Doc Ann longTypeMessage msg =         "\ESC[1;31mError\ESC[0m: " <> short <> "\n"     <>  "\n"@@ -1351,8 +1370,7 @@ insert :: Pretty a => a -> Doc Ann insert = Dhall.Util.insert -prettyTypeMessage-    :: (Eq a, Pretty a, ToTerm a) => TypeMessage s a -> ErrorMessages+prettyTypeMessage :: (Eq a, Pretty a) => TypeMessage s a -> ErrorMessages prettyTypeMessage (UnboundVariable x) = ErrorMessages {..}   -- We do not need to print variable name here. For the discussion see:   -- https://github.com/dhall-lang/dhall-haskell/pull/116@@ -2023,7 +2041,9 @@  prettyTypeMessage (InvalidPredicate expr0 expr1) = ErrorMessages {..}   where-    short = "Invalid predicate for ❰if❱"+    short = "Invalid predicate for ❰if❱: "+        <>  "\n"+        <>  Dhall.Diff.doc (Dhall.Diff.diffNormalized Bool expr1)      long =         "Explanation: Every ❰if❱ expression begins with a predicate which must have type \n\@@ -2672,6 +2692,55 @@         txt0 = insert expr0         txt1 = insert expr1 +prettyTypeMessage (CompletionSchemaMustBeARecord expr0 expr1) = ErrorMessages {..} + where+   short = "The completion schema must be a record" ++   long = +        "Explanation: You can complete records using the ❰::❱ operator:                  \n\+        \                                                                                \n\+        \    ┌─────────────────────────────────────────────────────────────────────────┐ \n\+        \    │ {Type = {foo : Bool, bar : Natural}, default = {bar = 2}::{foo = True}} │ \n\+        \    └─────────────────────────────────────────────────────────────────────────┘ \n\+        \                                                                                \n\+        \... The left-hand side of :: must be a record with 'Type' and 'default' keys    \n\+        \                                                                                \n\+        \You tried to record complete the following value:                               \n\+        \                                                                                \n\+        \" <> txt0 <> "\n\+        \                                                                                \n\+        \... which is not a record. It is:                                               \n\+        \                                                                                \n\+        \" <> txt1 <> "\n"+      where+        txt0 = insert expr0+        txt1 = insert expr1++prettyTypeMessage (InvalidRecordCompletion fieldName expr0) = ErrorMessages {..} + where+   short = "Completion schema is missing a field: " <> pretty fieldName++   long = +        "Explanation: You can complete records using the ❰::❱ operator like this:\n\+        \                                                                                \n\+        \    ┌─────────────────────────────────────────────────────────────────────────┐ \n\+        \    │ {Type = {foo : Bool, bar : Natural}, default = {bar = 2}::{foo = True}} │ \n\+        \    └─────────────────────────────────────────────────────────────────────────┘ \n\+        \                                                                                \n\+        \... but you need to have both Type and default fields in the completion schema  \n\+        \    (the record on the left of the the ::).                                     \n\+        \                                                                                \n\+        \You tried to do record completion using the schema:                             \n\+        \                                                                                \n\+        \" <> txt0 <> "\n\+        \                                                                                \n\+        \... which is missing the key:                                                   \n\+        \                                                                                \n\+        \" <> txt1 <> "\n"+      where+        txt0 = insert expr0+        txt1 = pretty fieldName+ prettyTypeMessage (MustCombineARecord c expr0 expr1) = ErrorMessages {..}   where     short = "You can only combine records"@@ -2820,7 +2889,7 @@  prettyTypeMessage (FieldCollision k) = ErrorMessages {..}   where-    short = "Field collision"+    short = "Field collision on: " <> Dhall.Pretty.Internal.prettyLabel k      long =         "Explanation: You can combine records or record types if they don't share any    \n\@@ -3030,9 +3099,12 @@       where         txt0 = insert (Text.intercalate ", " (Data.Set.toList ks)) -prettyTypeMessage (MissingHandler ks) = ErrorMessages {..}+prettyTypeMessage (MissingHandler exemplar ks) = ErrorMessages {..}   where-    short = "Missing handler"+    short = case Data.Set.toList ks of+         []       -> "Missing handler: " <> Dhall.Pretty.Internal.prettyLabel exemplar+         xs@(_:_) -> "Missing handlers: " <> (Pretty.hsep . Pretty.punctuate Pretty.comma +                                             . map Dhall.Pretty.Internal.prettyLabel $ exemplar:xs)      long =         "Explanation: You can ❰merge❱ the alternatives of a union using a record with one\n\@@ -3068,7 +3140,7 @@         \                                                                                \n\         \" <> txt0 <> "\n"       where-        txt0 = insert (Text.intercalate ", " (Data.Set.toList ks))+        txt0 = insert (Text.intercalate ", " (exemplar : Data.Set.toList ks))  prettyTypeMessage MissingMergeType =     ErrorMessages {..}@@ -3331,7 +3403,7 @@  prettyTypeMessage (HandlerNotAFunction k expr0) = ErrorMessages {..}   where-    short = "Handler is not a function"+    short = "Handler for "<> Dhall.Pretty.Internal.prettyLabel k <> " is not a function"      long =         "Explanation: You can ❰merge❱ the alternatives of a union using a record with one\n\@@ -3682,7 +3754,7 @@  prettyTypeMessage (MissingField k expr0) = ErrorMessages {..}   where-    short = "Missing record field"+    short = "Missing record field: " <> Dhall.Pretty.Internal.prettyLabel k      long =         "Explanation: You can only access fields on records, like this:                  \n\@@ -3724,7 +3796,7 @@  prettyTypeMessage (MissingConstructor k expr0) = ErrorMessages {..}   where-    short = "Missing constructor"+    short = "Missing constructor: " <> Dhall.Pretty.Internal.prettyLabel k      long =         "Explanation: You can access constructors from unions, like this:                \n\@@ -4246,35 +4318,24 @@     , typeMessage :: TypeMessage s a     } -instance (Eq a, Pretty s, Pretty a, ToTerm a) => Show (TypeError s a) where-    show = Pretty.renderString . Pretty.layoutPretty layoutOpts . Pretty.pretty--instance (Eq a, Pretty s, Pretty a, ToTerm a, Typeable s, Typeable a) => Exception (TypeError s a)+instance (Eq a, Pretty s, Pretty a) => Show (TypeError s a) where+    show = Pretty.renderString . Dhall.Pretty.layout . prettyTypeError -instance (Eq a, Pretty s, Pretty a, ToTerm a) => Pretty (TypeError s a) where-    pretty (TypeError ctx expr msg)-        = Pretty.unAnnotate-            (   "\n"-            <>  (   if null (Dhall.Context.toList ctx)-                    then ""-                    else prettyContext ctx <> "\n\n"-                )-            <>  shortTypeMessage msg <> "\n"-            <>  source-            )-      where-        prettyKV (key, val) =-            pretty key <> " : " <> Dhall.Util.snipDoc (pretty val)+instance (Eq a, Pretty s, Pretty a, Typeable s, Typeable a) => Exception (TypeError s a) -        prettyContext =-                Pretty.vsep-            .   map prettyKV-            .   reverse-            .   Dhall.Context.toList+instance (Eq a, Pretty s, Pretty a) => Pretty (TypeError s a) where+    pretty = Pretty.unAnnotate . prettyTypeError -        source = case expr of-            Note s _ -> pretty s-            _        -> mempty+prettyTypeError :: (Eq a, Pretty s, Pretty a) => TypeError s a -> Doc Ann+prettyTypeError (TypeError _ expr msg) =+    (   "\n"+    <>  shortTypeMessage msg <> "\n"+    <>  source+    )+  where+    source = case expr of+        Note s _ -> pretty s+        _        -> mempty  {-| Wrap a type error in this exception type to censor source code and     `Text` literals from the error message@@ -4284,7 +4345,7 @@     | Censored (TypeError Src X)  instance Show Censored where-    show = Pretty.renderString . Pretty.layoutPretty layoutOpts . Pretty.pretty+    show = Pretty.renderString . Dhall.Pretty.layout . Pretty.pretty  instance Exception Censored @@ -4349,6 +4410,10 @@         ListAppendMismatch <$> f a <*> f b     MustCombineARecord a b c ->         MustCombineARecord <$> pure a <*> f b <*> f c+    InvalidRecordCompletion a l -> +        InvalidRecordCompletion a <$> f l+    CompletionSchemaMustBeARecord l r -> +        CompletionSchemaMustBeARecord <$> f l <*> f r     CombineTypesRequiresRecordType a b ->         CombineTypesRequiresRecordType <$> f a <*> f b     RecordTypeMismatch a b c d ->@@ -4373,8 +4438,8 @@         pure MissingToMapType     UnusedHandler a ->         UnusedHandler <$> pure a-    MissingHandler a ->-        MissingHandler <$> pure a+    MissingHandler e a ->+        MissingHandler <$> pure e <*> pure a     HandlerInputTypeMismatch a b c ->         HandlerInputTypeMismatch <$> pure a <*> f b <*> f c     DisallowedHandlerType a b c d ->@@ -4432,37 +4497,40 @@ newtype DetailedTypeError s a = DetailedTypeError (TypeError s a)     deriving (Typeable) -instance (Eq a, Pretty s, Pretty a, ToTerm a) => Show (DetailedTypeError s a) where-    show = Pretty.renderString . Pretty.layoutPretty layoutOpts . Pretty.pretty+instance (Eq a, Pretty s, Pretty a) => Show (DetailedTypeError s a) where+    show = Pretty.renderString . Dhall.Pretty.layout . prettyDetailedTypeError -instance (Eq a, Pretty s, Pretty a, ToTerm a, Typeable s, Typeable a) => Exception (DetailedTypeError s a)+instance (Eq a, Pretty s, Pretty a, Typeable s, Typeable a) => Exception (DetailedTypeError s a) -instance (Eq a, Pretty s, Pretty a, ToTerm a) => Pretty (DetailedTypeError s a) where-    pretty (DetailedTypeError (TypeError ctx expr msg))-        = Pretty.unAnnotate-            (   "\n"-            <>  (   if null (Dhall.Context.toList ctx)-                    then ""-                    else prettyContext ctx <> "\n\n"-                )-            <>  longTypeMessage msg <> "\n"-            <>  "────────────────────────────────────────────────────────────────────────────────\n"-            <>  "\n"-            <>  source-            )-      where-        prettyKV (key, val) =-            pretty key <> " : " <> Dhall.Util.snipDoc (pretty val)+instance (Eq a, Pretty s, Pretty a) => Pretty (DetailedTypeError s a) where+    pretty = Pretty.unAnnotate . prettyDetailedTypeError -        prettyContext =-                Pretty.vsep-            .   map prettyKV-            .   reverse-            .   Dhall.Context.toList+prettyDetailedTypeError :: (Eq a, Pretty s, Pretty a) => DetailedTypeError s a -> Doc Ann+prettyDetailedTypeError (DetailedTypeError (TypeError ctx expr msg)) =+    (   "\n"+    <>  (   if null (Dhall.Context.toList ctx)+            then ""+            else prettyContext ctx <> "\n\n"+        )+    <>  longTypeMessage msg <> "\n"+    <>  "────────────────────────────────────────────────────────────────────────────────\n"+    <>  "\n"+    <>  source+    )+  where+    prettyKV (key, val) =+        Dhall.Util.snipDoc+            (Dhall.Pretty.Internal.prettyLabel key <> " : " <> Dhall.Pretty.prettyExpr val) -        source = case expr of-            Note s _ -> pretty s-            _        -> mempty+    prettyContext =+            Pretty.vsep+        .   map prettyKV+        .   reverse+        .   Dhall.Context.toList++    source = case expr of+        Note s _ -> pretty s+        _        -> mempty  {-| This function verifies that a custom context is well-formed so that     type-checking will not loop
src/Dhall/URL.hs view
@@ -6,7 +6,7 @@ import Data.Monoid ((<>)) import Data.Text (Text) -import Dhall.Core+import Dhall.Syntax     ( Scheme(..)     , URL(..)     , File(..)
src/Dhall/Util.hs view
@@ -12,23 +12,27 @@     , Output(..)     , getExpression     , getExpressionAndHeader+    , getExpressionAndHeaderFromStdinText+    , Header(..)     ) where +import Control.Exception (Exception(..))+import Control.Monad.IO.Class (MonadIO(..)) import Data.Bifunctor (first) import Data.Monoid ((<>)) import Data.String (IsString) import Data.Text (Text) import Data.Text.Prettyprint.Doc (Doc, Pretty)-import Dhall.Core (Expr, Import)-import Dhall.Parser (ParseError)+import Dhall.Parser (ParseError, Header(..)) import Dhall.Pretty (Ann)+import Dhall.Syntax (Expr, Import) import Dhall.Src (Src) +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.Text as Pretty-import qualified Dhall.Core+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 @@ -73,11 +77,11 @@ snipDoc :: Doc Ann -> Doc a snipDoc doc = Pretty.align (Pretty.pretty (snip text))   where-    stream = Pretty.layoutSmart Dhall.Pretty.layoutOpts doc+    stream = Dhall.Pretty.layout doc      ansiStream = fmap Dhall.Pretty.annToAnsiStyle stream -    text = Pretty.renderStrict ansiStream+    text = Pretty.Terminal.renderStrict ansiStream  takeEnd :: Int -> [a] -> [a] takeEnd n l = go (drop n l) l@@ -94,17 +98,19 @@ _ERROR :: IsString string => string _ERROR = "\ESC[1;31mError\ESC[0m" -get :: (String -> Text -> Either ParseError a) -> Censor -> Input -> IO a+get :: (String -> Text -> Either ParseError a) -> Censor -> InputOrTextFromStdin -> IO a get parser censor input = do     inText <- do         case input of-            InputFile file -> Data.Text.IO.readFile file-            StandardInput  -> Data.Text.IO.getContents+            Input_ (InputFile file) -> Data.Text.IO.readFile file+            Input_ StandardInput    -> Data.Text.IO.getContents+            StdinText text          -> pure text      let name =             case input of-                InputFile file -> file-                StandardInput  -> "(stdin)"+                Input_ (InputFile file) -> file+                Input_ StandardInput    -> "(stdin)"+                StdinText _             -> "(stdin)"      let result = parser name inText @@ -113,21 +119,36 @@                 NoCensor -> result                 Censor   -> first Dhall.Parser.censor result -    Dhall.Core.throws censoredResult+    throws censoredResult +{-| Convenience utility for converting `Either`-based exceptions to `IO`-based+    exceptions+-}+throws :: (Exception e, MonadIO io) => Either e a -> io a+throws (Left  e) = liftIO (Control.Exception.throwIO e)+throws (Right r) = return r+ -- | Set to `Censor` if you want to censor error text that might include secrets data Censor = NoCensor | Censor  -- | Path to input data Input = StandardInput | InputFile FilePath +-- | Path to input or raw input text, necessary since we can't read STDIN twice+data InputOrTextFromStdin = Input_ Input | StdinText Text+ -- | Path to output data Output = StandardOutput | OutputFile FilePath  -- | Convenient utility for retrieving an expression getExpression :: Censor -> Input -> IO (Expr Src Import)-getExpression = get Dhall.Parser.exprFromText+getExpression censor = get Dhall.Parser.exprFromText censor . Input_  -- | Convenient utility for retrieving an expression along with its header-getExpressionAndHeader :: Censor -> Input -> IO (Text, Expr Src Import)-getExpressionAndHeader = get Dhall.Parser.exprAndHeaderFromText+getExpressionAndHeader :: Censor -> Input -> IO (Header, Expr Src Import)+getExpressionAndHeader censor = get Dhall.Parser.exprAndHeaderFromText censor . Input_++-- | 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
tests/Dhall/Test/Dhall.hs view
@@ -57,8 +57,8 @@  data MyType = MyType { foo :: String , bar :: Natural } -wrongDhallType :: Dhall.Type MyType-wrongDhallType = Dhall.Type { .. }+wrongDhallType :: Dhall.Decoder MyType+wrongDhallType = Dhall.Decoder { .. }   where expected =           Dhall.Core.Record             ( Dhall.Map.fromList@@ -74,12 +74,12 @@         try ( Dhall.input wrongDhallType "{  bar = 0, foo = \"foo\" }")    let expectedMsg =-        "\ESC[1;31mError\ESC[0m: Invalid Dhall.Type                                                  \n\+        "\ESC[1;31mError\ESC[0m: Invalid Dhall.Decoder                                               \n\         \                                                                                \n\-        \Every Type must provide an extract function that succeeds if an expression      \n\-        \matches the expected type.  You provided a Type that disobeys this contract     \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 Type provided has the expected dhall type:                                  \n\+        \The Decoder provided has the expected dhall type:                               \n\         \                                                                                \n\         \↳ { bar : Natural, foo : Text }\n\         \                                                                                \n\@@ -97,7 +97,7 @@ -- https://github.com/dhall-lang/dhall-haskell/issues/915 shouldHandleUnionLiteral :: TestTree shouldHandleUnionLiteral = testCase "Marshal union literals" $ do-    let example :: Dhall.Type Bool+    let example :: Dhall.Decoder Bool         example = Dhall.union (Dhall.constructor "Test" Dhall.bool)      _ <- Dhall.input example "< Test : Bool >.Test True"@@ -106,15 +106,15 @@  shouldTreatAConstructorStoringUnitAsEmptyAlternative :: TestTree shouldTreatAConstructorStoringUnitAsEmptyAlternative = testCase "Handle unit constructors" $ do-    let exampleType :: Dhall.Type ()+    let exampleType :: Dhall.Decoder ()         exampleType = Dhall.union (Dhall.constructor "A" Dhall.unit)      () <- Dhall.input exampleType "< A >.A" -    let exampleInputType :: Dhall.InputType ()-        exampleInputType = Dhall.inputUnion (Dhall.inputConstructor "A")+    let exampleEncoder :: Dhall.Encoder ()+        exampleEncoder = Dhall.unionEncoder (Dhall.encodeConstructor "A") -    Dhall.embed exampleInputType () @=? Field (Union (Dhall.Map.singleton "A" Nothing)) "A"+    Dhall.embed exampleEncoder () @=? Field (Union (Dhall.Map.singleton "A" Nothing)) "A"  shouldHaveWorkingRecursiveFromDhall :: TestTree shouldHaveWorkingRecursiveFromDhall = testGroup "recursive FromDhall instance"
tests/Dhall/Test/Diff.hs view
@@ -10,11 +10,11 @@  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.Text as Pretty.Text 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@@ -50,13 +50,8 @@         let actualDiffDocument =                 Diff.doc (Diff.diffNormalized leftInput rightInput) <> "\n" -        let options =-                Pretty.LayoutOptions-                    { Pretty.layoutPageWidth = Pretty.Unbounded }--        let actualDiffText =-                Pretty.Text.renderStrict-                    (Pretty.layoutPretty options actualDiffDocument)+        let actualDiffText = Pretty.Text.renderStrict+                    (Dhall.Pretty.layout actualDiffDocument)          let message = "The diffed expressions did not match the expected output" 
tests/Dhall/Test/Format.hs view
@@ -4,6 +4,7 @@  import Data.Monoid (mempty, (<>)) import Data.Text (Text)+import Dhall.Parser (Header(..)) import Dhall.Pretty (CharacterSet(..)) import Test.Tasty (TestTree) @@ -43,6 +44,16 @@      return testTree +format :: CharacterSet -> (Header, Core.Expr Parser.Src Core.Import) -> Text+format characterSet (Header header, expr) =+    let doc =  Doc.pretty header+            <> Pretty.prettyCharacterSet characterSet expr+            <> "\n"++        docStream = Pretty.layout doc+    in+        Doc.Render.Text.renderStrict docStream+ formatTest :: CharacterSet -> Text -> TestTree formatTest characterSet prefix =     Tasty.HUnit.testCase (Text.unpack prefix) $ do@@ -51,14 +62,9 @@          inputText <- Text.IO.readFile inputFile -        (header, expr) <- Core.throws (Parser.exprAndHeaderFromText mempty inputText)--        let doc        =   Doc.pretty header-                       <>  Pretty.prettyCharacterSet characterSet expr-                       <>  "\n"-        let docStream  = Doc.layoutSmart Pretty.layoutOpts doc-        let actualText = Doc.Render.Text.renderStrict docStream+        headerAndExpr <- Core.throws (Parser.exprAndHeaderFromText mempty inputText) +        let actualText = format characterSet headerAndExpr         expectedText <- Text.IO.readFile outputFile          let message =
tests/Dhall/Test/Parser.hs view
@@ -10,9 +10,6 @@ import Test.Tasty (TestTree) import Turtle (FilePath, (</>)) -import qualified Codec.CBOR.Read      as CBOR-import qualified Codec.CBOR.Term      as CBOR-import qualified Codec.Serialise      as Serialise import qualified Control.Monad        as Monad import qualified Data.Bifunctor       as Bifunctor import qualified Data.ByteString      as ByteString@@ -26,6 +23,7 @@ import qualified Dhall.Test.Util      as Test.Util import qualified Test.Tasty           as Tasty import qualified Test.Tasty.HUnit     as Tasty.HUnit+import qualified Text.Printf          as Printf import qualified Turtle  parseDirectory :: FilePath@@ -91,7 +89,8 @@                       (Just " ")                       Nothing                       (Just " ")-                      (Note "0 " (NaturalLit 0)))+                      (Note "0 " (Note "0" (NaturalLit 0)))+                    )                     -- This 'Let' isn't wrapped in a 'Note'!                     (Let                       (Binding@@ -100,7 +99,7 @@                         (Just " ")                         Nothing                         (Just " ")-                        (Note "1 " (NaturalLit 1))+                        (Note "1 " (Note "1" (NaturalLit 1)))                       )                       (Note "let z = 2 in x"                         (Let@@ -110,10 +109,14 @@                             (Just " ")                             Nothing                             (Just " ")-                            (Note "2 " (NaturalLit 2))+                            (Note "2 " (Note "2" (NaturalLit 2)))                           )-                          (Note "x"-                            (Var (V "x" 0))))))))+                          (Note "x" (Var (V "x" 0)))+                        )+                      )+                    )+                  )+                )          let msg = "Unexpected parse result" @@ -124,8 +127,13 @@     let expectedFailures =             -- This is a bug created by a parsing performance             -- improvement-            [ parseDirectory </> "success/unit/MergeParenAnnotation" ]+            [ parseDirectory </> "success/unit/MergeParenAnnotation" +            -- https://github.com/dhall-lang/dhall-haskell/issues/1454+            , parseDirectory </> "success/missingFoo"+            , parseDirectory </> "success/missingSlash"+            ]+     let pathString = Text.unpack path      Test.Util.testCase path expectedFailures $ do@@ -133,18 +141,20 @@          encoded <- ByteString.Lazy.readFile (pathString <> "B.dhallb") -        expression <- Core.throws (Parser.exprFromText mempty text)+        expression <- case Parser.exprFromText mempty text of+            Left  exception  -> Tasty.HUnit.assertFailure (show exception)+            Right expression -> return expression -        let term = Binary.encodeExpression expression+        let bytes = Binary.encodeExpression (Core.denote expression) -        let bytes = Serialise.serialise term+        let render =+                  concatMap (Printf.printf "%02x ")+                . ByteString.Lazy.unpack          Monad.unless (encoded == bytes) $ do-            ("", expected) <- Core.throws (CBOR.deserialiseFromBytes CBOR.decodeTerm encoded)-             let message = "The expected CBOR representation doesn't match the actual one\n"-                          ++ "expected: " ++ show expected ++ "\n but got: " ++ show term-                          ++ "\n expr: " ++ show expression+                          ++ "expected: " ++ render encoded ++ "\n but got: " ++ render bytes+                          ++ "\n expr: " ++ show (Core.denote expression :: Expr Void Import)              Tasty.HUnit.assertFailure message @@ -152,35 +162,11 @@ shouldNotParse :: Text -> TestTree shouldNotParse path = do     let expectedFailures =-            [ -- These two unexpected successes are due to not correctly-              -- requiring non-empty whitespace after the `:` in a type-              -- annotation-              parseDirectory </> "failure/unit/ImportEnvWrongEscape.dhall"--              -- Other spacing related unexpected successes:-            , parseDirectory </> "failure/spacing/AnnotationNoSpace.dhall"-            , parseDirectory </> "failure/spacing/ApplicationNoSpace1.dhall"-            , parseDirectory </> "failure/spacing/ApplicationNoSpace2.dhall"-            , parseDirectory </> "failure/spacing/AssertNoSpace.dhall"-            , parseDirectory </> "failure/spacing/ForallNoSpace.dhall"-            , parseDirectory </> "failure/spacing/ImportAltNoSpace.dhall"-            , parseDirectory </> "failure/spacing/ImportHashedNoSpace.dhall"-            , parseDirectory </> "failure/spacing/LambdaNoSpace.dhall"-            , parseDirectory </> "failure/spacing/ListLitEmptyNoSpace.dhall"-            , parseDirectory </> "failure/spacing/MergeAnnotationNoSpace3.dhall"-            , parseDirectory </> "failure/spacing/MergeNoSpace2.dhall"-            , parseDirectory </> "failure/spacing/NaturalPlusNoSpace.dhall"-            , parseDirectory </> "failure/spacing/RecordTypeNoSpace.dhall"-            , parseDirectory </> "failure/spacing/ToMapAnnotNoSpace.dhall"-            , parseDirectory </> "failure/spacing/UnionTypeNoSpace.dhall"--            , parseDirectory </> "failure/ImportHeadersExteriorHash.dhall"--              -- For parsing performance reasons the implementation+            [ -- For parsing performance reasons the implementation               -- treats a missing type annotation on an empty list as               -- as a type-checking failure instead of a parse failure,               -- but this might be fixable.-            , parseDirectory </> "failure/unit/ListLitEmptyMissingAnnotation.dhall"+              parseDirectory </> "failure/unit/ListLitEmptyMissingAnnotation.dhall"             , parseDirectory </> "failure/unit/ListLitEmptyAnnotation.dhall"                -- The same performance improvements also broke the@@ -202,16 +188,29 @@  shouldDecode :: Text -> TestTree shouldDecode pathText = do-    let expectedFailures = []+    let expectedFailures =+          [ {- Note that this test actually successfully decodes the value, but+               mistakenly decodes the value to `_` instead of `x`.  This is+               because the 55799 tag causes normal decoding to fail, so it falls+               back to treating the `"x"` as a version tag instead of a label. +               Either way, fixing 55799 decoding would cause this test to pass+               again.+            -}+            binaryDecodeDirectory </> "success/unit/SelfDescribeCBORX2"+          , binaryDecodeDirectory </> "success/unit/SelfDescribeCBORX3"+          ]+     let pathString = Text.unpack pathText      Test.Util.testCase pathText expectedFailures (do         bytes <- ByteString.Lazy.readFile (pathString <> "A.dhallb") -        term <- Core.throws (Serialise.deserialiseOrFail bytes)--        decodedExpression <- Core.throws (Binary.decodeExpression term)+        decodedExpression <- case Binary.decodeExpression bytes of+            Left exception ->+                Tasty.HUnit.assertFailure (show exception)+            Right decodedExpression ->+                return decodedExpression          text <- Text.IO.readFile (pathString <> "B.dhall") @@ -223,7 +222,7 @@         let message =                 "The decoded expression didn't match the parsed expression" -        Tasty.HUnit.assertEqual message decodedExpression strippedExpression )+        Tasty.HUnit.assertEqual message strippedExpression decodedExpression )  shouldNotDecode :: Text -> TestTree shouldNotDecode pathText = do@@ -234,8 +233,6 @@     Test.Util.testCase pathText expectedFailures (do         bytes <- ByteString.Lazy.readFile (pathString <> ".dhallb") -        term <- Core.throws (Serialise.deserialiseOrFail bytes)--        case Binary.decodeExpression term :: Either Binary.DecodingFailure (Expr Void Import) of+        case Binary.decodeExpression bytes :: Either Binary.DecodingFailure (Expr Void Import) of             Left _ -> return ()             Right _ -> Tasty.HUnit.assertFailure "Unexpected successful decode" )
tests/Dhall/Test/QuickCheck.hs view
@@ -1,18 +1,19 @@ {-# LANGUAGE DataKinds           #-} {-# LANGUAGE OverloadedStrings   #-}-{-# LANGUAGE RecordWildCards     #-}-{-# LANGUAGE StandaloneDeriving  #-}-{-# LANGUAGE TypeOperators       #-} {-# LANGUAGE RankNTypes          #-}+{-# LANGUAGE RecordWildCards     #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators       #-}+{-# LANGUAGE ViewPatterns #-}  {-# OPTIONS_GHC -fno-warn-orphans #-}  module Dhall.Test.QuickCheck where -import Codec.Serialise (DeserialiseFailure(..)) import Data.Either (isRight) import Data.Either.Validation (Validation(..))+import Data.Monoid ((<>))+import Data.Void (Void) import Dhall (ToDhall(..), FromDhall(..), auto, extract, inject, embed, Vector) import Dhall.Map (Map) import Dhall.Core@@ -37,19 +38,21 @@ import Data.Typeable (Typeable, typeRep) import Data.Proxy (Proxy(..)) import Dhall.Set (Set)+import Dhall.Parser (Header(..), createHeader)+import Dhall.Pretty (CharacterSet(..)) import Dhall.Src (Src(..))+import Dhall.Test.Format (format) import Dhall.TypeCheck (Typer, TypeError) import Generic.Random (Weights, W, (%), (:+)(..)) import Test.QuickCheck-    (Arbitrary(..), Gen, Positive(..), Property, NonNegative(..), genericShrink, (===), (==>))+    ( Arbitrary(..), Gen, Positive(..), Property, NonNegative(..)+    , genericShrink, suchThat, (===), (==>)) import Test.QuickCheck.Instances () import Test.Tasty (TestTree) import Test.Tasty.QuickCheck (QuickCheckTests(..)) import Text.Megaparsec (SourcePos(..), Pos)  import qualified Control.Spoon-import qualified Codec.Serialise-import qualified Data.Coerce import qualified Data.List import qualified Data.Sequence import qualified Data.SpecialValues@@ -63,6 +66,7 @@ import qualified Dhall.Core import qualified Dhall.Diff import qualified Dhall.Map+import qualified Dhall.Parser as Parser import qualified Dhall.Set import qualified Dhall.TypeCheck import qualified Generic.Random@@ -72,13 +76,6 @@ import qualified Test.Tasty.QuickCheck import qualified Text.Megaparsec       as Megaparsec -newtype DeserialiseFailureWithEq = D DeserialiseFailure-    deriving (Show)--instance Eq DeserialiseFailureWithEq where-    D (DeserialiseFailure aL bL) == D (DeserialiseFailure aR bR) =-        aL == aR && bL == bR- instance (Arbitrary a, Ord a) => Arbitrary (Set a) where   arbitrary = Dhall.Set.fromList <$> arbitrary   shrink = map Dhall.Set.fromList . shrink . Dhall.Set.toList@@ -140,6 +137,42 @@         , (1, fmap (\x -> x - (2 ^ (64 :: Int))) arbitrary)         ] +instance Arbitrary CharacterSet where+    arbitrary = Test.QuickCheck.elements [ ASCII, Unicode ]++instance Arbitrary Header where+    arbitrary = do+      let commentChar =+              Test.QuickCheck.frequency+                  [ (20, Test.QuickCheck.elements [' ' .. '\DEL'])+                  , ( 1, arbitrary)+                  ]++          commentText = Text.pack <$> Test.QuickCheck.listOf commentChar++          multiline = do+              txt <- commentText+              pure $ "{-" <> txt <> "-}"++          singleline = do+              txt <- commentText `suchThat` (not . Text.isInfixOf "\n")+              endOfLine <- Test.QuickCheck.elements ["\n", "\r\n"]+              pure $ "--" <> txt <> endOfLine++          newlines = Text.concat <$> Test.QuickCheck.listOf (pure "\n")++      comments <- do+          n <- Test.QuickCheck.choose (0, 2)+          Test.QuickCheck.vectorOf n $ Test.QuickCheck.oneof+              [ multiline+              , singleline+              , newlines+              ]++      pure . createHeader $ Text.unlines comments++    shrink (Header txt) = createHeader . Text.pack <$> shrink (Text.unpack txt)+ instance (Ord k, Arbitrary k, Arbitrary v) => Arbitrary (Map k v) where     arbitrary = do         n   <- Test.QuickCheck.choose (0, 2)@@ -241,6 +274,8 @@             % (1 :: W "NaturalTimes")             % (1 :: W "Integer")             % (7 :: W "IntegerLit")+            % (1 :: W "IntegerClamp")+            % (1 :: W "IntegerNegate")             % (1 :: W "IntegerShow")             % (1 :: W "IntegerToDouble")             % (1 :: W "Double")@@ -368,21 +403,11 @@  binaryRoundtrip :: Expr () Import -> Property binaryRoundtrip expression =-        wrap-            (fmap-                Dhall.Binary.decodeExpression-                (Codec.Serialise.deserialiseOrFail-                  (Codec.Serialise.serialise-                    (Dhall.Binary.encodeExpression expression)-                  )-                )-            )-    === wrap (Right (Right (Dhall.Core.denote expression :: Expr () Import)))+        Dhall.Binary.decodeExpression (Dhall.Binary.encodeExpression denotedExpression)+    === Right denotedExpression   where-    wrap-        :: Either DeserialiseFailure       a-        -> Either DeserialiseFailureWithEq a-    wrap = Data.Coerce.coerce+    denotedExpression :: Expr Void Import+    denotedExpression = Dhall.Core.denote expression  everythingWellTypedNormalizes :: Expr () () -> Property everythingWellTypedNormalizes expression =@@ -450,17 +475,23 @@ embedThenExtractIsIdentity     :: forall a. (ToDhall a, FromDhall a, Eq a, Typeable a, Arbitrary a, Show a)     => Proxy a-    -> (String, Property, QuickCheckTests)+    -> (String, Property, TestTree -> TestTree) embedThenExtractIsIdentity p =     ( "Embedding then extracting is identity for " ++ show (typeRep p)     , Test.QuickCheck.property (prop :: a -> Bool)-    , QuickCheckTests 1000+    , adjustQuickCheckTests 1000     )   where     prop a = case extract auto (embed inject a) of         Success a' -> a == a'         Failure _  -> False +idempotenceTest :: CharacterSet -> Header -> Expr Src Import -> Property+idempotenceTest characterSet header expr =+    let once = format characterSet (header, expr)+    in case Parser.exprAndHeaderFromText mempty once of+        Right (format characterSet -> twice) -> once === twice+        Left _ -> Test.QuickCheck.discard  tests :: TestTree tests =@@ -468,31 +499,31 @@         "QuickCheck"         [ ( "Binary serialization should round-trip"           , Test.QuickCheck.property binaryRoundtrip-          , QuickCheckTests 100+          , adjustQuickCheckTests 100           )         , ( "everything well-typed should normalize"           , Test.QuickCheck.property everythingWellTypedNormalizes-          , QuickCheckTests 100000+          , adjustQuickCheckTests 100000           )         , ( "isNormalized should be consistent with normalize"           , Test.QuickCheck.property isNormalizedIsConsistentWithNormalize-          , QuickCheckTests 10000+          , adjustQuickCheckTests 10000           )         , ( "normalizeWithM should be consistent with normalize"           , Test.QuickCheck.property normalizeWithMIsConsistentWithNormalize-          , QuickCheckTests 10000+          , adjustQuickCheckTests 10000           )         , ( "An expression should have no difference with itself"           , Test.QuickCheck.property isSameAsSelf-          , QuickCheckTests 10000+          , adjustQuickCheckTests 10000           )         , ( "Inferred types should be normalized"           , Test.QuickCheck.property inferredTypesAreNormalized-          , QuickCheckTests 10000+          , adjustQuickCheckTests 10000           )         , ( "Normalizing an expression doesn't change its inferred type"           , Test.QuickCheck.property normalizingAnExpressionDoesntChangeItsInferredType-          , QuickCheckTests 10000+          , adjustQuickCheckTests 10000           )         , embedThenExtractIsIdentity (Proxy :: Proxy (Text.Text))         , embedThenExtractIsIdentity (Proxy :: Proxy [Nat.Natural])@@ -504,13 +535,28 @@         , embedThenExtractIsIdentity (Proxy :: Proxy (Vector Double))         , embedThenExtractIsIdentity (Proxy :: Proxy (Data.Map.Map Double Bool))         , embedThenExtractIsIdentity (Proxy :: Proxy (HashMap.HashMap Double Bool))+        , ( "Formatting should be idempotent"+          , Test.QuickCheck.property idempotenceTest++            -- FIXME: While this test is flaky, we set the number of test cases+            -- to 0 by subtracting the default number of tests (100).+            -- To run the test manually, use e.g.+            --    --quickcheck-tests 1000+          , Test.Tasty.adjustOption (subtract (QuickCheckTests 100))+          )         ] +adjustQuickCheckMaxRatio :: Int -> TestTree -> TestTree+adjustQuickCheckMaxRatio maxSize =+    Test.Tasty.adjustOption (max $ Test.Tasty.QuickCheck.QuickCheckMaxRatio maxSize) +adjustQuickCheckTests :: Int -> TestTree -> TestTree+adjustQuickCheckTests nTests =+    -- Using adjustOption instead of withMaxSuccess allows us to override the number of tests+    -- with the --quickcheck-tests CLI option.+    Test.Tasty.adjustOption (max $ QuickCheckTests nTests) -testProperties' :: String -> [(String, Property, QuickCheckTests)] -> TestTree+testProperties' :: String -> [(String, Property, TestTree -> TestTree)] -> TestTree testProperties' name = Test.Tasty.testGroup name . map f   where-    -- Using adjustOption instead of withMaxSuccess allows us to override the number of tests-    -- with the --quickcheck-tests CLI option.-    f (n, p, nTests) = Test.Tasty.adjustOption (max nTests) (Test.Tasty.QuickCheck.testProperty n p)+    f (n, p, adjust) = adjust (Test.Tasty.QuickCheck.testProperty n p)
tests/Dhall/Test/Regression.hs view
@@ -42,6 +42,7 @@         , issue1131a         , issue1131b         , issue1341+        , issue1584         , parsing0         , typeChecking0         , typeChecking1@@ -55,7 +56,7 @@  unnamedFields :: TestTree unnamedFields = Test.Tasty.HUnit.testCase "Unnamed Fields" (do-    let ty = Dhall.auto :: Dhall.Type Foo+    let ty = Dhall.auto :: Dhall.Decoder Foo     Test.Tasty.HUnit.assertEqual "Good type" (Dhall.expected ty)         (Dhall.Core.Union             (Dhall.Map.fromList@@ -69,14 +70,14 @@             )         ) -    let inj = Dhall.inject :: Dhall.InputType Foo+    let inj = Dhall.inject :: Dhall.Encoder Foo     Test.Tasty.HUnit.assertEqual "Good ToDhall" (Dhall.declared inj) (Dhall.expected ty) -    let tu_ty = Dhall.auto :: Dhall.Type (Integer, Bool)+    let tu_ty = Dhall.auto :: Dhall.Decoder (Integer, Bool)     Test.Tasty.HUnit.assertEqual "Auto Tuple" (Dhall.expected tu_ty) (Dhall.Core.Record (             Dhall.Map.fromList [ ("_1",Dhall.Core.Integer),("_2",Dhall.Core.Bool) ])) -    let tu_in = Dhall.inject :: Dhall.InputType (Integer, Bool)+    let tu_in = Dhall.inject :: Dhall.Encoder (Integer, Bool)     Test.Tasty.HUnit.assertEqual "Inj. Tuple" (Dhall.declared tu_in) (Dhall.expected tu_ty)      return () )@@ -90,7 +91,7 @@ issue126 :: TestTree issue126 = Test.Tasty.HUnit.testCase "Issue #126" (do     e <- Util.code "''\nfoo\nbar\n''"-    Util.normalize' e @?= "\"foo\\nbar\\n\"" )+    Util.normalize' e @?= "''\nfoo\nbar\n''" )  issue151 :: TestTree issue151 = Test.Tasty.HUnit.testCase "Issue #151" (do@@ -147,7 +148,7 @@     source <- Data.Text.IO.readFile "./tests/regression/issue216b.dhall"     e <- Util.code source     let doc       = Data.Text.Prettyprint.Doc.pretty e-    let docStream = Data.Text.Prettyprint.Doc.layoutSmart Dhall.Pretty.layoutOpts doc+    let docStream = Dhall.Pretty.layout doc     let text0 = Data.Text.Prettyprint.Doc.Render.Text.renderLazy docStream      text1 <- Data.Text.Lazy.IO.readFile "./tests/regression/issue216b.dhall"@@ -179,6 +180,13 @@     let actual = Dhall.Core.V "x" 0 `Dhall.Core.freeIn` nan     let msg    = "NaN shouldn't contain any free variables"     Test.Tasty.HUnit.assertEqual msg False actual)++issue1584 :: TestTree+issue1584 = Test.Tasty.HUnit.testCase "Issue #1584" (do+    -- This test ensures that we can parse variables with keyword prefixes+    -- (e.g. `ifX`)+    _ <- Util.code "./tests/regression/issue1584.dhall"+    return () )  parsing0 :: TestTree parsing0 = Test.Tasty.HUnit.testCase "Parsing regression #0" (do
tests/diff/function.txt view
@@ -2,5 +2,5 @@ → … → …@- 1     + 0-  + → …
+ tests/diff/insideList.txt view
@@ -0,0 +1,7 @@+[ …+, { y = - 4+        + 5+  , …+  }+]+
+ tests/diff/insideListA.dhall view
@@ -0,0 +1,3 @@+[ { x = 1, y = 2 }+, { x = 3, y = 4 }+]
+ tests/diff/insideListB.dhall view
@@ -0,0 +1,3 @@+[ { x = 1, y = 2 }+, { x = 3, y = 5 }+]
tests/format/concatSepB.dhall view
@@ -23,7 +23,7 @@                       status                 )                 Status.Empty-        +         in  merge { Empty = "", NonEmpty = λ(result : Text) → result } status  let example0 = assert : concatSep ", " [ "ABC", "DEF", "GHI" ] ≡ "ABC, DEF, GHI"
+ tests/format/envVarsA.dhall view
@@ -0,0 +1,1 @@+[ env:x, env:"1", env:" ", env:"\\", env:"." ]
+ tests/format/envVarsB.dhall view
@@ -0,0 +1,1 @@+[ env:x, env:"1", env:" ", env:"\\", env:"." ]
tests/format/escapeSingleQuotedOpenInterpolationB.dhall view
@@ -1,1 +1,3 @@-"\${\n"+''+''${+''
tests/format/headerB.dhall view
@@ -1,3 +1,3 @@ {- bla -}-  + True
+ tests/format/importAltPrecedenceA.dhall view
@@ -0,0 +1,1 @@+a ? b || c
+ tests/format/importAltPrecedenceB.dhall view
@@ -0,0 +1,1 @@+a ? b || c
tests/format/innerMultilineB.dhall view
@@ -1,1 +1,11 @@-{ inner = "\none\n\ntwo\n\nthree\n\n" }+{ inner =+    ''++    one++    two++    three++    ''+}
+ tests/format/interpolation0A.dhall view
@@ -0,0 +1,1 @@+"foo\n${a} bar"
+ tests/format/interpolation0B.dhall view
@@ -0,0 +1,3 @@+''+foo+${a} bar''
+ tests/format/issue1400-1A.dhall view
@@ -0,0 +1,14 @@+{ conversation =+    [ { author = "robert", content = [] }+    , { author = "robert", content = [] }+    , { author =+          "bob"+      , content =+          [ text+              ''+              any line going past the 80 characters boundary (e.g. this one is 82)+              ''+          ]+      }+    ]+}
+ tests/format/issue1400-1B.dhall view
@@ -0,0 +1,13 @@+{ conversation =+    [ { author = "robert", content = [] }+    , { author = "robert", content = [] }+    , { author = "bob"+      , content =+          [ text+              ''+              any line going past the 80 characters boundary (e.g. this one is 82)+              ''+          ]+      }+    ]+}
+ tests/format/issue1400-2A.dhall view
@@ -0,0 +1,14 @@+let Tagged+    : Type → Type+    =   λ ( a+          : Type+          )+      → { field :+            Text+        , nesting :+              ./Nesting sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335+            ? ./Nesting+        , contents : a+        }++in  Tagged
+ tests/format/issue1400-2B.dhall view
@@ -0,0 +1,11 @@+let Tagged+    : Type → Type+    =   λ(a : Type)+      → { field : Text+        , nesting :+              ./Nesting sha256:6284802edd41d5d725aa1ec7687e614e21ad1be7e14dd10996bfa9625105c335+            ? ./Nesting+        , contents : a+        }++in  Tagged
tests/format/issue1413B.dhall view
@@ -1,5 +1,5 @@ let foo =-    +     {- test -}       "hello" 
+ tests/format/issue1545-1A.dhall view
@@ -0,0 +1,1 @@+"\n\tx"
+ tests/format/issue1545-1B.dhall view
@@ -0,0 +1,3 @@+''++${"\t"}x''
+ tests/format/issue1545-2A.dhall view
@@ -0,0 +1,1 @@+"\n x"
+ tests/format/issue1545-2B.dhall view
@@ -0,0 +1,3 @@+''++${" "}x''
+ tests/format/issue183A.dhall view
@@ -0,0 +1,11 @@+    let foo = 1++in    λ(bar : Integer)+    →     let exposePort =+                  λ(portSpec : { ext : Integer, int : Integer })+                → Integer/show portSpec.ext ++ ":" ++ Integer/show portSpec.int+      +      in  let exposeSamePort =+                λ(port : Integer) → exposePort { ext = port, int = port }+      +      in  { blah = bar }
+ tests/format/issue183B.dhall view
@@ -0,0 +1,11 @@+let foo = 1++in    λ(bar : Integer)+    → let exposePort =+              λ(portSpec : { ext : Integer, int : Integer })+            → Integer/show portSpec.ext ++ ":" ++ Integer/show portSpec.int++      in  let exposeSamePort =+                λ(port : Integer) → exposePort { ext = port, int = port }++          in  { blah = bar }
tests/format/letNewlineCommentsB.dhall view
@@ -5,5 +5,5 @@         : {- bbbbbbbbbbbbbbbbbbbbb           -} Natural         = {- ddddddddddddddddd -} 2-    +     in  x
+ tests/format/multilineArgumentA.dhall view
@@ -0,0 +1,1 @@+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff xxxxxxxxxxxxxxxx "\n"
+ tests/format/multilineArgumentB.dhall view
@@ -0,0 +1,3 @@+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff+  xxxxxxxxxxxxxxxx+  "\n"
tests/format/multilineB.dhall view
@@ -1,1 +1,3 @@-"ABC\nDEF"+''+ABC+DEF''
+ tests/format/multilineTrailingSingleQuoteA.dhall view
@@ -0,0 +1,1 @@+"\n'"
+ tests/format/multilineTrailingSingleQuoteB.dhall view
@@ -0,0 +1,3 @@+''++${"'"}''
+ tests/format/multilineTrailingWhitespaceA.dhall view
@@ -0,0 +1,1 @@+{ x = "  \n\nfoo  \n" }
+ tests/format/multilineTrailingWhitespaceB.dhall view
@@ -0,0 +1,7 @@+{ x =+    ''+      ++    foo  +    ''+}
+ tests/format/nestedAnnotationA.dhall view
@@ -0,0 +1,1 @@+([] : a) : b
+ tests/format/nestedAnnotationB.dhall view
@@ -0,0 +1,1 @@+([] : a) : b
+ tests/format/stringWithNullA.dhall view
@@ -0,0 +1,1 @@+"\u0000 \$ \\ \n ☺"
+ tests/format/stringWithNullB.dhall view
@@ -0,0 +1,3 @@+''+${"\u0000"} $ \ +${" "}☺''
+ tests/format/textLitNewlinesOnlyA.dhall view
@@ -0,0 +1,1 @@+"\n\n"
+ tests/format/textLitNewlinesOnlyB.dhall view
@@ -0,0 +1,1 @@+"\n\n"
+ tests/regression/issue1584.dhall view
@@ -0,0 +1,19 @@+[ let ifX = 1 in ifX+, let thenX = 1 in thenX+, let elseX = 1 in elseX+, let letX = 1 in letX+, let inX = 1 in inX+, let usingX = 1 in usingX+{- Fixing this case appears to be difficult for the current parser+   implementation+-}+-- , let missingX = 1 in missingX+, let asX = 1 in asX+, let InfinityX = 1 in InfinityX+, let NaNX = 1 in NaNX+, let mergeX = 1 in mergeX+, let SomeX = 1 in SomeX+, let toMapX = 1 in toMapX+, let assertX = 1 in assertX+, let forallX = 1 in forallX+]