-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A configuration language guaranteed to terminate -- -- Dhall is an explicitly typed configuration language that is not Turing -- complete. Despite being Turing incomplete, Dhall is a real programming -- language with a type-checker and evaluator. -- -- Use this library to parse, type-check, evaluate, and pretty-print the -- Dhall configuration language. This package also includes an executable -- which type-checks a Dhall file and reduces the file to a fully -- evaluated normal form. -- -- Read Dhall.Tutorial to learn how to use this library @package dhall @version 1.28.0 -- | This is a utility module that consolidates all Context-related -- operations module Dhall.Context -- | A (Context a) associates Text labels with values of -- type a. Each Text label can correspond to multiple -- values of type a -- -- The Context is used for type-checking when (a = Expr -- X) -- --
-- match (insert k v ctx) = Just (k, v, ctx) -- match empty = Nothing --match :: Context a -> Maybe (Text, a, Context a) -- | Look up a key by name and index -- --
-- lookup _ _ empty = Nothing -- lookup k 0 (insert k v c) = Just v -- lookup k n (insert k v c) = lookup k (n - 1) c -- lookup k n (insert j v c) = lookup k n c -- k /= j --lookup :: Text -> Int -> Context a -> Maybe a -- | Return all key-value associations as a list -- --
-- toList empty = [] -- toList (insert k v ctx) = (k, v) : toList ctx --toList :: Context a -> [(Text, a)] instance GHC.Base.Functor Dhall.Context.Context -- | This module provides implementations of cryptographic utilities that -- only work for GHC (as opposed to GHCJS) module Dhall.Crypto -- | A SHA256 digest newtype SHA256Digest SHA256Digest :: ByteString -> SHA256Digest [unSHA256Digest] :: SHA256Digest -> ByteString -- | Attempt to interpret a ByteString as a SHA256Digest, -- returning Nothing if the conversion fails sha256DigestFromByteString :: ByteString -> Maybe SHA256Digest -- | Hash a ByteString and return the hash as a SHA256Digest sha256Hash :: ByteString -> SHA256Digest instance Data.ByteArray.Types.ByteArrayAccess Dhall.Crypto.SHA256Digest instance Control.DeepSeq.NFData Dhall.Crypto.SHA256Digest instance GHC.Classes.Ord Dhall.Crypto.SHA256Digest instance GHC.Generics.Generic Dhall.Crypto.SHA256Digest instance GHC.Classes.Eq Dhall.Crypto.SHA256Digest instance GHC.Show.Show Dhall.Crypto.SHA256Digest -- | Map type used to represent records and unions module Dhall.Map -- | A Map that remembers the original ordering of keys -- -- This is primarily used so that formatting preserves field order -- -- This is done primarily to avoid a dependency on -- insert-ordered-containers and also to improve performance data Map k v -- | Create an empty Map empty :: Ord k => Map k v -- | Create a Map from a single key-value pair -- --
-- >>> singleton "A" 1
-- fromList [("A",1)]
--
singleton :: k -> v -> Map k v
-- | Create a Map from a list of key-value pairs
--
--
-- >>> fromList [("B",1),("A",2)] -- The map preserves order
-- fromList [("B",1),("A",2)]
--
-- >>> fromList [("A",1),("A",2)] -- For duplicates, later values take precedence
-- fromList [("A",2)]
--
--
-- Note that this handling of duplicates means that fromList is
-- not a monoid homomorphism:
--
-- -- >>> fromList [(1, True)] <> fromList [(1, False)] -- fromList [(1,True)] -- -- >>> fromList ([(1, True)] <> [(1, False)]) -- fromList [(1,False)] --fromList :: Ord k => [(k, v)] -> Map k v -- | Create a Map from a list of key-value pairs with a combining -- function. -- --
-- >>> fromListWithKey (\k v1 v2 -> k ++ v1 ++ v2) [("B","v1"),("A","v2"),("B","v3")]
-- fromList [("B","Bv3v1"),("A","v2")]
--
fromListWithKey :: Ord k => (k -> v -> v -> v) -> [(k, v)] -> Map k v
-- | Create a Map from a single key-value pair.
--
-- Any further operations on this map will not retain the order of the
-- keys.
--
--
-- >>> unorderedSingleton "A" 1
-- fromList [("A",1)]
--
unorderedSingleton :: k -> v -> Map k v
-- | Create a Map from a list of key-value pairs
--
-- Any further operations on this map will not retain the order of the
-- keys.
--
--
-- >>> unorderedFromList []
-- fromList []
--
-- >>> unorderedFromList [("B",1),("A",2)] -- The map /doesn't/ preserve order
-- fromList [("A",2),("B",1)]
--
-- >>> unorderedFromList [("A",1),("A",2)] -- For duplicates, later values take precedence
-- fromList [("A",2)]
--
unorderedFromList :: Ord k => [(k, v)] -> Map k v
-- | Sort the keys of a Map, forgetting the original ordering
--
-- -- sort (sort x) = sort x ---- --
-- >>> sort (fromList [("B",1),("A",2)])
-- fromList [("A",2),("B",1)]
--
sort :: Map k v -> Map k v
-- | Check if the keys of a Map are already sorted
--
-- -- isSorted (sort m) = True ---- --
-- >>> isSorted (fromList [("B",1),("A",2)]) -- Sortedness is based only on keys
-- False
--
-- >>> isSorted (fromList [("A",2),("B",1)])
-- True
--
isSorted :: Eq k => Map k v -> Bool
-- | Insert a key-value pair into a Map, overriding any previous
-- value stored underneath the same key, if present
--
-- -- insert = insertWith (\v _ -> v) ---- --
-- >>> insert "C" 1 (fromList [("B",2),("A",3)]) -- Values are inserted on left
-- fromList [("C",1),("B",2),("A",3)]
--
-- >>> insert "C" 1 (fromList [("C",2),("A",3)]) -- New value takes precedence
-- fromList [("C",1),("A",3)]
--
insert :: Ord k => k -> v -> Map k v -> Map k v
-- | Insert a key-value pair into a Map, using the supplied function
-- to combine the new value with any old value underneath the same key,
-- if present
--
--
-- >>> insertWith (+) "C" 1 (fromList [("B",2),("A",3)]) -- No collision
-- fromList [("C",1),("B",2),("A",3)]
--
-- >>> insertWith (+) "C" 1 (fromList [("C",2),("A",3)]) -- Collision
-- fromList [("C",3),("A",3)]
--
insertWith :: Ord k => (v -> v -> v) -> k -> v -> Map k v -> Map k v
-- | Delete a key from a Map if present, otherwise return the
-- original Map
--
--
-- >>> delete "B" (fromList [("C",1),("B",2),("A",3)])
-- fromList [("C",1),("A",3)]
--
-- >>> delete "D" (fromList [("C",1),("B",2),("A",3)])
-- fromList [("C",1),("B",2),("A",3)]
--
delete :: Ord k => k -> Map k v -> Map k v
-- | Keep all values that satisfy the given predicate
--
--
-- >>> filter even (fromList [("C",3),("B",2),("A",1)])
-- fromList [("B",2)]
--
-- >>> filter odd (fromList [("C",3),("B",2),("A",1)])
-- fromList [("C",3),("A",1)]
--
filter :: Ord k => (a -> Bool) -> Map k a -> Map k a
-- | Restrict a Map to only those keys found in a
-- Data.Set.Set.
--
--
-- >>> restrictKeys (fromList [("A",1),("B",2)]) (Data.Set.fromList ["A"])
-- fromList [("A",1)]
--
restrictKeys :: Ord k => Map k a -> Set k -> Map k a
-- | 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 -> Set k -> Map k a
-- | Transform all values in a Map using the supplied function,
-- deleting the key if the function returns Nothing
--
--
-- >>> mapMaybe Data.Maybe.listToMaybe (fromList [("C",[1]),("B",[]),("A",[3])])
-- fromList [("C",1),("A",3)]
--
mapMaybe :: Ord k => (a -> Maybe b) -> Map k a -> Map k b
-- | Retrieve a key from a Map
--
-- -- lookup k mempty = empty -- -- lookup k (x <> y) = lookup k y <|> lookup k x ---- --
-- >>> lookup "A" (fromList [("B",1),("A",2)])
-- Just 2
--
-- >>> lookup "C" (fromList [("B",1),("A",2)])
-- Nothing
--
lookup :: Ord k => k -> Map k v -> Maybe v
-- | Check if a key belongs to a Map
--
-- -- member k mempty = False -- -- member k (x <> y) = member k x || member k y ---- --
-- >>> member "A" (fromList [("B",1),("A",2)])
-- True
--
-- >>> member "C" (fromList [("B",1),("A",2)])
-- False
--
member :: Ord k => k -> Map k v -> Bool
-- | Retrieve the first key, value of the Map, if present, and also
-- returning the rest of the Map.
--
-- -- uncons mempty = empty -- -- uncons (singleton k v) = (k, v, mempty) ---- --
-- >>> uncons (fromList [("C",1),("B",2),("A",3)])
-- Just ("C",1,fromList [("B",2),("A",3)])
--
-- >>> uncons (fromList [])
-- Nothing
--
uncons :: Ord k => Map k v -> Maybe (k, v, Map k v)
-- |
-- >>> size (fromList [("A",1)])
-- 1
--
size :: Map k v -> Int
-- | Combine two Maps, preferring keys from the first Map
--
-- -- union = unionWith (\v _ -> v) ---- --
-- >>> union (fromList [("D",1),("C",2)]) (fromList [("B",3),("A",4)])
-- fromList [("D",1),("C",2),("B",3),("A",4)]
--
-- >>> union (fromList [("D",1),("C",2)]) (fromList [("C",3),("A",4)])
-- fromList [("D",1),("C",2),("A",4)]
--
union :: Ord k => Map k v -> Map k v -> Map k v
-- | Combine two Maps using a combining function for colliding keys
--
--
-- >>> unionWith (+) (fromList [("D",1),("C",2)]) (fromList [("B",3),("A",4)])
-- fromList [("D",1),("C",2),("B",3),("A",4)]
--
-- >>> unionWith (+) (fromList [("D",1),("C",2)]) (fromList [("C",3),("A",4)])
-- fromList [("D",1),("C",5),("A",4)]
--
unionWith :: Ord k => (v -> v -> v) -> Map k v -> Map k v -> Map k v
-- | A generalised unionWith.
--
--
-- >>> outerJoin Left Left (\k a b -> Right (k, a, b)) (fromList [("A",1),("B",2)]) (singleton "A" 3)
-- fromList [("A",Right ("A",1,3)),("B",Left 2)]
--
--
-- This function is much inspired by the Data.Semialign.Semialign
-- class.
outerJoin :: Ord k => (a -> c) -> (b -> c) -> (k -> a -> b -> c) -> Map k a -> Map k b -> Map k c
-- | Combine two Map on their shared keys, keeping the value from
-- the first Map
--
-- -- intersection = intersectionWith (\v _ -> v) ---- --
-- >>> intersection (fromList [("C",1),("B",2)]) (fromList [("B",3),("A",4)])
-- fromList [("B",2)]
--
intersection :: Ord k => Map k a -> Map k b -> Map k a
-- | Combine two Maps on their shared keys, using the supplied
-- function to combine values from the first and second Map
--
--
-- >>> intersectionWith (+) (fromList [("C",1),("B",2)]) (fromList [("B",3),("A",4)])
-- fromList [("B",5)]
--
intersectionWith :: Ord k => (a -> b -> c) -> Map k a -> Map k b -> Map k c
-- | Compute the difference of two Maps by subtracting all keys from
-- the second Map from the first Map
--
--
-- >>> difference (fromList [("C",1),("B",2)]) (fromList [("B",3),("A",4)])
-- fromList [("C",1)]
--
difference :: Ord k => Map k a -> Map k b -> Map k a
-- | Transform the values of a Map using their corresponding key
--
-- -- mapWithKey (pure id) = id -- -- mapWithKey (liftA2 (.) f g) = mapWithKey f . mapWithKey g ---- --
-- mapWithKey f mempty = mempty -- -- mapWithKey f (x <> y) = mapWithKey f x <> mapWithKey f y ---- --
-- >>> mapWithKey (,) (fromList [("B",1),("A",2)])
-- fromList [("B",("B",1)),("A",("A",2))]
--
mapWithKey :: (k -> a -> b) -> Map k a -> Map k b
-- | Traverse all of the key-value pairs in a Map, in their original
-- order
--
--
-- >>> traverseWithKey (,) (fromList [("B",1),("A",2)])
-- ("BA",fromList [("B",1),("A",2)])
--
traverseWithKey :: Ord k => Applicative f => (k -> a -> f b) -> Map k a -> f (Map k b)
-- | Same as traverseWithKey, except that the order of effects is
-- not necessarily the same as the order of the keys
unorderedTraverseWithKey :: Ord k => Applicative f => (k -> a -> f b) -> Map k a -> f (Map k b)
-- | Traverse all of the key-value pairs in a Map, not preserving
-- their original order, where the result of the computation can be
-- forgotten.
--
-- Note that this is a strict traversal, fully traversing the map even
-- when the Applicative is lazy in the remaining elements.
unorderedTraverseWithKey_ :: Ord k => Applicative f => (k -> a -> f ()) -> Map k a -> f ()
-- | Fold all of the key-value pairs in a Map, in their original
-- order
--
--
-- >>> foldMapWithKey (,) (fromList [("B",[1]),("A",[2])])
-- ("BA",[1,2])
--
foldMapWithKey :: (Monoid m, Ord k) => (k -> a -> m) -> Map k a -> m
-- | Convert a Map to a list of key-value pairs in the original
-- order of keys
--
--
-- >>> toList (fromList [("B",1),("A",2)])
-- [("B",1),("A",2)]
--
toList :: Ord k => Map k v -> [(k, v)]
-- | Convert a Map to a list of key-value pairs in ascending order
-- of keys
toAscList :: Map k v -> [(k, v)]
-- | Convert a Dhall.Map.Map to a
-- Data.Map.Map
--
--
-- >>> toMap (fromList [("B",1),("A",2)]) -- Order is lost upon conversion
-- fromList [("A",2),("B",1)]
--
toMap :: Map k v -> Map k v
-- | Return the keys from a Map in their original order
--
--
-- >>> keys (fromList [("B",1),("A",2)])
-- ["B","A"]
--
keys :: Map k v -> [k]
-- | Return the Data.Set.Set of the keys
--
--
-- >>> keysSet (fromList [("B",1),("A",2)])
-- fromList ["A","B"]
--
keysSet :: Map k v -> Set k
-- | Return the values from a Map in their original order.
--
--
-- >>> elems (fromList [("B",1),("A",2)])
-- [1,2]
--
elems :: Ord k => Map k v -> [v]
instance (Control.DeepSeq.NFData k, Control.DeepSeq.NFData v) => Control.DeepSeq.NFData (Dhall.Map.Map k v)
instance GHC.Generics.Generic (Dhall.Map.Map k v)
instance (Data.Data.Data k, Data.Data.Data v, GHC.Classes.Ord k) => Data.Data.Data (Dhall.Map.Map k v)
instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Dhall.Map.Keys a)
instance GHC.Generics.Generic (Dhall.Map.Keys a)
instance Data.Data.Data a => Data.Data.Data (Dhall.Map.Keys a)
instance (Data.Data.Data k, Data.Data.Data v, Language.Haskell.TH.Syntax.Lift k, Language.Haskell.TH.Syntax.Lift v, GHC.Classes.Ord k) => Language.Haskell.TH.Syntax.Lift (Dhall.Map.Map k v)
instance (GHC.Classes.Ord k, GHC.Classes.Eq v) => GHC.Classes.Eq (Dhall.Map.Map k v)
instance (GHC.Classes.Ord k, GHC.Classes.Ord v) => GHC.Classes.Ord (Dhall.Map.Map k v)
instance GHC.Base.Functor (Dhall.Map.Map k)
instance GHC.Classes.Ord k => Data.Foldable.Foldable (Dhall.Map.Map k)
instance GHC.Classes.Ord k => Data.Traversable.Traversable (Dhall.Map.Map k)
instance GHC.Classes.Ord k => GHC.Base.Semigroup (Dhall.Map.Map k v)
instance GHC.Classes.Ord k => GHC.Base.Monoid (Dhall.Map.Map k v)
instance (GHC.Show.Show k, GHC.Show.Show v, GHC.Classes.Ord k) => GHC.Show.Show (Dhall.Map.Map k v)
instance GHC.Classes.Ord k => GHC.Exts.IsList (Dhall.Map.Map k v)
instance (Data.Data.Data a, Language.Haskell.TH.Syntax.Lift a) => Language.Haskell.TH.Syntax.Lift (Dhall.Map.Keys a)
-- | This module contains some useful utilities copy-and-pasted from the
-- lens library to avoid a dependency which are used internally
-- and also re-exported for convenience
module Dhall.Optics
-- | Identical to Control.Lens.rewriteOf
rewriteOf :: ASetter a b a b -> (b -> Maybe a) -> a -> b
-- | Identical to Control.Lens.transformOf
transformOf :: ASetter a b a b -> (b -> b) -> a -> b
-- | Identical to Control.Lens.rewriteMOf
rewriteMOf :: Monad m => LensLike (WrappedMonad m) a b a b -> (b -> m (Maybe a)) -> a -> m b
-- | Identical to Control.Lens.transformMOf
transformMOf :: Monad m => LensLike (WrappedMonad m) a b a b -> (b -> m b) -> a -> m b
-- | Identical to Control.Lens.mapMOf
mapMOf :: LensLike (WrappedMonad m) s t a b -> (a -> m b) -> s -> m t
-- | This module only exports ways of constructing a Set, retrieving List,
-- Set, and Seq representations of the same data, as well as a novel
-- "difference" function. Any other Set-like or List-like functionality
-- should be obtained through toSet and toList, respectively.
module Dhall.Set
-- | This is a variation on Data.Set.Set that
-- remembers the original order of elements. This ensures that ordering
-- is not lost when formatting Dhall code
data Set a
Set :: Set a -> Seq a -> Set a
-- | Convert a Set to a list, preserving the original order of the
-- elements
toList :: Set a -> [a]
-- | Convert a Set to a list of ascending elements
toAscList :: Set a -> [a]
-- | Convert to an unordered Data.Set.Set
toSet :: Set a -> Set a
-- | Convert to an ordered Seq
toSeq :: Set a -> Seq a
-- | Convert a list to a Set, remembering the element order
fromList :: Ord a => [a] -> Set a
-- | Convert a Data.Set.Set to a sorted Set
fromSet :: Set a -> Set a
-- | Append an element to the end of a Set
append :: Ord a => a -> Set a -> Set a
-- | The empty Set
empty :: Set a
-- | Returns, in order, all elements of the first Set not present in the
-- second. (It doesn't matter in what order the elements appear in the
-- second Set.)
difference :: Ord a => Set a -> Set a -> [a]
-- | Sort the set elements, forgetting their original ordering.
--
-- -- >>> sort (fromList [2, 1]) == fromList [1, 2] -- True --sort :: Ord a => Set a -> Set a -- |
-- >>> isSorted (fromList [2, 1]) -- False -- -- >>> isSorted (fromList [1, 2]) -- True --isSorted :: Ord a => Set a -> Bool -- |
-- >>> null (fromList [1]) -- False -- -- >>> null (fromList []) -- True --null :: Set a -> Bool -- |
-- >>> size (fromList [1]) -- 1 --size :: Set a -> Int instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Dhall.Set.Set a) instance (Data.Data.Data a, GHC.Classes.Ord a) => Data.Data.Data (Dhall.Set.Set a) instance GHC.Show.Show a => GHC.Show.Show (Dhall.Set.Set a) instance GHC.Generics.Generic (Dhall.Set.Set a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Dhall.Set.Set a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Dhall.Set.Set a) instance (Data.Data.Data a, Language.Haskell.TH.Syntax.Lift a, GHC.Classes.Ord a) => Language.Haskell.TH.Syntax.Lift (Dhall.Set.Set a) instance Data.Foldable.Foldable Dhall.Set.Set -- | This module provides the Src type used for source spans in -- error messages module Dhall.Src -- | Source code extract data Src Src :: !SourcePos -> !SourcePos -> Text -> Src [srcStart] :: Src -> !SourcePos [srcEnd] :: Src -> !SourcePos [srcText] :: Src -> Text instance Control.DeepSeq.NFData Dhall.Src.Src instance GHC.Show.Show Dhall.Src.Src instance GHC.Classes.Ord Dhall.Src.Src instance GHC.Generics.Generic Dhall.Src.Src instance GHC.Classes.Eq Dhall.Src.Src instance Data.Data.Data Dhall.Src.Src instance Language.Haskell.TH.Syntax.Lift Dhall.Src.Src instance Data.Text.Prettyprint.Doc.Internal.Pretty Dhall.Src.Src -- | 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 -- | Supported version strings -- -- This exists primarily for backwards compatibility for expressions -- encoded before Dhall removed version tags from the binary encoding data StandardVersion -- | No version string NoVersion :: StandardVersion -- | Version "5.0.0" V_5_0_0 :: StandardVersion -- | Version "4.0.0" V_4_0_0 :: StandardVersion -- | Version "3.0.0" V_3_0_0 :: StandardVersion -- | Version "2.0.0" V_2_0_0 :: StandardVersion -- | Version "1.0.0" V_1_0_0 :: StandardVersion -- | Render a StandardVersion as Expr renderStandardVersion :: StandardVersion -> Text -- | Encode a Dhall expression as a CBOR-encoded ByteString encodeExpression :: Expr Void Import -> ByteString -- | Decode a Dhall expression from a CBOR Term decodeExpression :: Serialise (Expr s a) => ByteString -> Either DecodingFailure (Expr s a) -- | This indicates that a given CBOR-encoded ByteString did not -- correspond to a valid Dhall expression newtype DecodingFailure CBORIsNotDhall :: ByteString -> DecodingFailure instance GHC.Classes.Eq Dhall.Binary.DecodingFailure instance GHC.Enum.Bounded Dhall.Binary.StandardVersion instance GHC.Enum.Enum Dhall.Binary.StandardVersion instance GHC.Exception.Type.Exception Dhall.Binary.DecodingFailure instance GHC.Show.Show Dhall.Binary.DecodingFailure instance Codec.Serialise.Class.Serialise (Dhall.Syntax.Expr Data.Void.Void Data.Void.Void) instance Codec.Serialise.Class.Serialise (Dhall.Syntax.Expr Data.Void.Void Dhall.Syntax.Import) -- | This module contains logic for pretty-printing expressions, including -- support for syntax highlighting module Dhall.Pretty -- | Annotation type used to tag elements in a pretty-printed document for -- syntax highlighting purposes data Ann -- | Used for syntactic keywords Keyword :: Ann -- | Syntax punctuation such as commas, parenthesis, and braces Syntax :: Ann -- | Record labels Label :: Ann -- | Literals such as integers and strings Literal :: Ann -- | Builtin types and values Builtin :: Ann -- | Operators Operator :: Ann -- | Convert annotations to their corresponding color for syntax -- highlighting purposes annToAnsiStyle :: Ann -> AnsiStyle -- | Pretty print an expression prettyExpr :: Pretty a => Expr s a -> Doc Ann -- | This type determines whether to render code as ASCII or -- Unicode data CharacterSet ASCII :: CharacterSet Unicode :: CharacterSet -- | Pretty-print an Expr using the given CharacterSet. -- -- prettyCharacterSet largely ignores Notes. Notes -- do however matter for the layout of let-blocks: -- --
-- >>> let inner = Let (Binding Nothing "x" Nothing Nothing Nothing (NaturalLit 1)) (Var (V "x" 0)) :: Expr Src () -- -- >>> prettyCharacterSet ASCII (Let (Binding Nothing "y" Nothing Nothing Nothing (NaturalLit 2)) inner) -- let y = 2 let x = 1 in x -- -- >>> prettyCharacterSet ASCII (Let (Binding Nothing "y" Nothing Nothing Nothing (NaturalLit 2)) (Note (Src unusedSourcePos unusedSourcePos "") inner)) -- let y = 2 in let x = 1 in x ---- -- This means the structure of parsed let-blocks is preserved. prettyCharacterSet :: Pretty a => CharacterSet -> Expr Src a -> Doc Ann -- | 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 :: Doc ann -> SimpleDocStream ann -- | Default layout options layoutOpts :: LayoutOptions -- | This module provides functionality for concisely displaying the -- difference between two expressions -- -- For example, this is used in type errors to explain why the actual -- type does not match the expected type module Dhall.Diff -- | This type is a Doc enriched with a same flag to -- efficiently track if any difference was detected data Diff Diff :: Bool -> Doc Ann -> Diff [same] :: Diff -> Bool [doc] :: Diff -> Doc Ann -- | Render the difference between the normal form of two expressions diffNormalized :: (Eq a, Pretty a) => Expr s a -> Expr s a -> Diff -- | Render the difference between two expressions diff :: (Eq a, Pretty a) => Expr Void a -> Expr Void a -> Diff instance GHC.Base.Semigroup Dhall.Diff.Diff instance GHC.Base.Monoid Dhall.Diff.Diff instance Data.String.IsString Dhall.Diff.Diff -- | Parse Dhall tokens. Even though we don't have a tokenizer per-se this module Dhall.Parser.Token -- | Returns True if the given Int is a valid Unicode -- codepoint validCodepoint :: Int -> Bool -- | Parse 0 or more whitespace characters (including comments) -- -- This corresponds to the whsp rule in the official grammar whitespace :: Parser () -- | Parse 1 or more whitespace characters (including comments) -- -- This corresponds to the whsp1 rule in the official grammar nonemptyWhitespace :: Parser () -- | Parse a valid Bash environment variable name -- -- This corresponds to the bash-environment-variable rule in the -- official grammar bashEnvironmentVariable :: Parser Text -- | Parse a valid POSIX environment variable name, which permits a wider -- range of characters than a Bash environment variable name -- -- This corresponds to the posix-environment-variable rule in -- the official grammar posixEnvironmentVariable :: Parser Text -- | The pathComponent function uses this type to distinguish -- whether to parse a URL path component or a file path component data ComponentType URLComponent :: ComponentType FileComponent :: ComponentType -- | A variation on text that doesn't quote the expected in error -- messages text :: Text -> Parser Text -- | A variation on char that doesn't quote the expected token in -- error messages char :: Char -> Parser Char -- | Parse a File file_ :: ComponentType -> Parser File -- | Parse a label (e.g. a variable/field/alternative name) -- -- Rejects labels that match built-in names (e.g. Natural/even) -- -- This corresponds to the nonreserved-label rule in the -- official grammar label :: Parser Text -- | Same as label except that built-in names are allowed -- -- This corresponds to the any-label rule in the official -- grammar anyLabel :: Parser Text -- | Parse a braced sequence of comma-separated labels -- -- For example, this is used to parse the record projection syntax -- -- This corresponds to the labels rule in the official grammar labels :: Parser (Set Text) -- | Parse an HTTP(S) URL without trailing whitespace -- -- This corresponds to the http-raw rule in the official grammar httpRaw :: Parser URL -- | Parse a hex digit (uppercase or lowercase) -- -- This corresponds to the HEXDIG rule in the official grammar hexdig :: Char -> Bool -- | Parse an identifier (i.e. a variable or built-in) -- -- Variables can have an optional index to disambiguate shadowed -- variables -- -- This corresponds to the identifier rule from the official -- grammar identifier :: Parser Var -- | Parse a hexademical number and convert to the corresponding Int hexNumber :: Parser Int -- | Parse a Expr literal -- -- This corresponds to the double-literal rule from the official -- grammar doubleLiteral :: Parser Double -- | Parse a signed Infinity -- -- This corresponds to the minus-infinity-literal and -- plus-infinity-literal rules from the official grammar doubleInfinity :: Parser Double -- | Parse a Expr literal -- -- This corresponds to the natural-literal rule from the -- official grammar naturalLiteral :: Parser Natural -- | Parse an Expr literal -- -- This corresponds to the integer-literal rule from the -- official grammar integerLiteral :: Parser Integer -- | Parse the Optional built-in -- -- This corresponds to the Optional rule from the official -- grammar _Optional :: Parser () -- | Parse the if keyword -- -- This corresponds to the if rule from the official grammar _if :: Parser () -- | Parse the then keyword -- -- This corresponds to the then rule from the official grammar _then :: Parser () -- | Parse the else keyword -- -- This corresponds to the else rule from the official grammar _else :: Parser () -- | Parse the let keyword -- -- This corresponds to the let rule from the official grammar _let :: Parser () -- | Parse the in keyword -- -- This corresponds to the in rule from the official grammar _in :: Parser () -- | Parse the as keyword -- -- This corresponds to the as rule from the official grammar _as :: Parser () -- | Parse the using keyword -- -- This corresponds to the using rule from the official grammar _using :: Parser () -- | Parse the merge keyword -- -- This corresponds to the merge rule from the official grammar _merge :: Parser () -- | Parse the toMap keyword -- -- This corresponds to the toMap rule from the official grammar _toMap :: Parser () -- | Parse the assert keyword -- -- This corresponds to the assert rule from the official grammar _assert :: Parser () -- | Parse the Some built-in -- -- This corresponds to the Some rule from the official grammar _Some :: Parser () -- | Parse the None built-in -- -- This corresponds to the None rule from the official grammar _None :: Parser () -- | Parse the Natural/fold built-in -- -- This corresponds to the Natural-fold rule from the official -- grammar _NaturalFold :: Parser () -- | Parse the Natural/build built-in -- -- This corresponds to the Natural-build rule from the official -- grammar _NaturalBuild :: Parser () -- | Parse the Natural/isZero built-in -- -- This corresponds to the Natural-isZero rule from the official -- grammar _NaturalIsZero :: Parser () -- | Parse the Natural/even built-in -- -- This corresponds to the Natural-even rule from the official -- grammar _NaturalEven :: Parser () -- | Parse the Natural/odd built-in -- -- This corresponds to the Natural-odd rule from the official -- grammar _NaturalOdd :: Parser () -- | Parse the Natural/toInteger built-in -- -- This corresponds to the Natural-toInteger rule from the -- official grammar _NaturalToInteger :: Parser () -- | Parse the Natural/show built-in -- -- This corresponds to the Natural-show rule from the official -- grammar _NaturalShow :: Parser () -- | Parse the Natural/subtract built-in -- -- This corresponds to the Natural-subtract rule from the -- official grammar _NaturalSubtract :: Parser () -- | Parse the Integer/clamp built-in -- -- This corresponds to the Integer-clamp rule from the official -- grammar _IntegerClamp :: Parser () -- | Parse the Integer/negate built-in -- -- This corresponds to the Integer-negate rule from the official -- grammar _IntegerNegate :: Parser () -- | Parse the Integer/show built-in -- -- This corresponds to the Integer-show rule from the official -- grammar _IntegerShow :: Parser () -- | Parse the Integer/toDouble built-in -- -- This corresponds to the Integer-toDouble rule from the -- official grammar _IntegerToDouble :: Parser () -- | Parse the Double/show built-in -- -- This corresponds to the Double-show rule from the official -- grammar _DoubleShow :: Parser () -- | Parse the List/build built-in -- -- This corresponds to the List-build rule from the official -- grammar _ListBuild :: Parser () -- | Parse the List/fold built-in -- -- This corresponds to the List-fold rule from the official -- grammar _ListFold :: Parser () -- | Parse the List/length built-in -- -- This corresponds to the List-length rule from the official -- grammar _ListLength :: Parser () -- | Parse the List/head built-in -- -- This corresponds to the List-head rule from the official -- grammar _ListHead :: Parser () -- | Parse the List/last built-in -- -- This corresponds to the List-last rule from the official -- grammar _ListLast :: Parser () -- | Parse the List/indexed built-in -- -- This corresponds to the List-indexed rule from the official -- grammar _ListIndexed :: Parser () -- | Parse the List/reverse built-in -- -- This corresponds to the List-reverse rule from the official -- grammar _ListReverse :: Parser () -- | Parse the Optional/fold built-in -- -- This corresponds to the Optional-fold rule from the official -- grammar _OptionalFold :: Parser () -- | Parse the Optional/build built-in -- -- This corresponds to the Optional-build rule from the official -- grammar _OptionalBuild :: Parser () -- | Parse the Bool built-in -- -- This corresponds to the Bool rule from the official grammar _Bool :: Parser () -- | Parse the Natural built-in -- -- This corresponds to the Natural rule from the official -- grammar _Natural :: Parser () -- | Parse the Integer built-in -- -- This corresponds to the Integer rule from the official -- grammar _Integer :: Parser () -- | Parse the Double built-in -- -- This corresponds to the Double rule from the official grammar _Double :: Parser () -- | Parse the Text built-in -- -- This corresponds to the Text rule from the official grammar _Text :: Parser () -- | Parse the Text/show built-in -- -- This corresponds to the Text-show rule from the official -- grammar _TextShow :: Parser () -- | Parse the List built-in -- -- This corresponds to the List rule from the official grammar _List :: Parser () -- | Parse the True built-in -- -- This corresponds to the True rule from the official grammar _True :: Parser () -- | Parse the False built-in -- -- This corresponds to the False rule from the official grammar _False :: Parser () -- | Parse a NaN literal -- -- This corresponds to the NaN rule from the official grammar _NaN :: Parser () -- | Parse the Type built-in -- -- This corresponds to the Type rule from the official grammar _Type :: Parser () -- | Parse the Kind built-in -- -- This corresponds to the Kind rule from the official grammar _Kind :: Parser () -- | Parse the Sort built-in -- -- This corresponds to the Sort rule from the official grammar _Sort :: Parser () -- | Parse the Location keyword -- -- This corresponds to the Location rule from the official -- grammar _Location :: Parser () -- | Parse the = symbol _equal :: Parser () -- | Parse the || symbol _or :: Parser () -- | Parse the + symbol _plus :: Parser () -- | Parse the ++ symbol _textAppend :: Parser () -- | Parse the # symbol _listAppend :: Parser () -- | Parse the && symbol _and :: Parser () -- | Parse the * symbol _times :: Parser () -- | Parse the == symbol _doubleEqual :: Parser () -- | Parse the != symbol _notEqual :: Parser () -- | Parse the . symbol _dot :: Parser () -- | Parse the { symbol _openBrace :: Parser () -- | Parse the } symbol _closeBrace :: Parser () -- | Parse the [] symbol _openBracket :: Parser () -- | Parse the ] symbol _closeBracket :: Parser () -- | Parse the < symbol _openAngle :: Parser () -- | Parse the > symbol _closeAngle :: Parser () -- | Parse the | symbol _bar :: Parser () -- | Parse the , symbol _comma :: Parser () -- | Parse the ( symbol _openParens :: Parser () -- | Parse the ) symbol _closeParens :: Parser () -- | Parse the : symbol _colon :: Parser () -- | Parse the @ symbol _at :: Parser () -- | Parse the equivalence symbol (=== or ≡) _equivalent :: Parser () -- | Parse the missing keyword _missing :: Parser () -- | Parse the ? symbol _importAlt :: Parser () -- | Parse the record combine operator (/\ or ∧) _combine :: Parser () -- | Parse the record type combine operator (//\\ or ⩓) _combineTypes :: Parser () -- | Parse the record "prefer" operator (// or ⫽) _prefer :: Parser () -- | Parse a lambda (\ or λ) _lambda :: Parser () -- | Parse a forall (forall or ∀) _forall :: Parser () -- | Parse a right arrow (-> or →) _arrow :: Parser () -- | Parse a double colon (::) _doubleColon :: Parser () -- | Parsing Dhall expressions. module Dhall.Parser.Expression -- | Get the current source position getSourcePos :: MonadParsec e s m => m SourcePos -- | Get the current source offset (in tokens) getOffset :: MonadParsec e s m => m Int -- | Set the current source offset setOffset :: MonadParsec e s m => Int -> m () -- | Wrap a Parser to still match the same text but return only the -- Src span src :: Parser a -> Parser Src -- | Wrap a Parser to still match the same text, but to wrap the -- resulting Expr in a Note constructor containing the -- Src span noted :: Parser (Expr Src a) -> Parser (Expr Src a) -- | Parse a complete expression (with leading and trailing whitespace) -- -- This corresponds to the complete-expression rule from the -- official grammar completeExpression :: Parser a -> Parser (Expr Src a) -- | Parse an "import expression" -- -- This is not the same thing as fmap Embed. This -- parses any expression of the same or higher precedence as an import -- expression (such as a selector expression). For example, this parses -- (1) -- -- This corresponds to the import-expression rule from the -- official grammar importExpression :: Parser a -> Parser (Expr Src a) -- | For efficiency (and simplicity) we only expose two parsers from the -- result of the parsers function, since these are the only -- parsers needed outside of this module data Parsers a Parsers :: Parser (Expr Src a) -> Parser (Expr Src a) -> Parsers a [completeExpression_] :: Parsers a -> Parser (Expr Src a) [importExpression_] :: Parsers a -> Parser (Expr Src a) -- | Given a parser for imports, parsers :: Parser a -> Parsers a -- | Parse an environment variable import -- -- This corresponds to the env rule from the official grammar env :: Parser ImportType -- | Parse a local import without trailing whitespace localOnly :: Parser ImportType -- | Parse a local import -- -- This corresponds to the local rule from the official grammar local :: Parser ImportType -- | Parse an HTTP(S) import -- -- This corresponds to the http rule from the official grammar http :: Parser ImportType -- | Parse a Missing import -- -- This corresponds to the missing rule from the official -- grammar missing :: Parser ImportType -- | Parse an ImportType -- -- This corresponds to the import-type rule from the official -- grammar importType_ :: Parser ImportType -- | Parse a SHA256Digest -- -- This corresponds to the hash rule from the official grammar importHash_ :: Parser SHA256Digest -- | Parse an ImportHashed -- -- This corresponds to the import-hashed rule from the official -- grammar importHashed_ :: Parser ImportHashed -- | Parse an Import -- -- This corresponds to the import rule from the official grammar import_ :: Parser Import -- | Same as Data.Text.splitOn, except always returning a -- NonEmpty result splitOn :: Text -> Text -> NonEmpty Text -- | Split Chunks by lines linesLiteral :: Chunks s a -> NonEmpty (Chunks s a) -- | Flatten several Chunks back into a single Chunks by -- inserting newlines unlinesLiteral :: NonEmpty (Chunks s a) -> Chunks s a -- | Returns True if the Chunks represents a blank line emptyLine :: Chunks s a -> Bool -- | Return the leading whitespace for a Chunks literal leadingSpaces :: Chunks s a -> Text -- | Drop the first n characters for a Chunks literal dropLiteral :: Int -> Chunks s a -> Chunks s a -- | Convert a single-quoted Chunks literal to the equivalent -- double-quoted Chunks literal toDoubleQuoted :: Chunks Src a -> Chunks Src a -- | 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 -- | Constants for a pure type system -- -- The axioms are: -- --
-- ⊦ Type : Kind -- ⊦ Kind : Sort ---- -- ... and the valid rule pairs are: -- --
-- ⊦ Type ↝ Type : Type -- Functions from terms to terms (ordinary functions) -- ⊦ Kind ↝ Type : Type -- Functions from types to terms (type-polymorphic functions) -- ⊦ Sort ↝ Type : Type -- Functions from kinds to terms -- ⊦ Kind ↝ Kind : Kind -- Functions from types to types (type-level functions) -- ⊦ Sort ↝ Kind : Sort -- Functions from kinds to types (kind-polymorphic functions) -- ⊦ Sort ↝ Sort : Sort -- Functions from kinds to kinds (kind-level functions) ---- -- Note that Dhall does not support functions from terms to types and -- therefore Dhall is not a dependently typed language data Const Type :: Const Kind :: Const Sort :: Const -- | Internal representation of a directory that stores the path components -- in reverse order -- -- In other words, the directory /foo/bar/baz is encoded as -- Directory { components = [ "baz", "bar", "foo" ] } newtype Directory Directory :: [Text] -> Directory [components] :: Directory -> [Text] -- | A File is a directory followed by one additional path -- component representing the file name data File File :: Directory -> Text -> File [directory] :: File -> Directory [file] :: File -> Text -- | The beginning of a file path which anchors subsequent path components data FilePrefix -- | Absolute path Absolute :: FilePrefix -- | Path relative to . Here :: FilePrefix -- | Path relative to .. Parent :: FilePrefix -- | Path relative to ~ Home :: FilePrefix -- | Reference to an external resource data Import Import :: ImportHashed -> ImportMode -> Import [importHashed] :: Import -> ImportHashed [importMode] :: Import -> ImportMode -- | A ImportType extended with an optional hash for semantic -- integrity checks data ImportHashed ImportHashed :: Maybe SHA256Digest -> ImportType -> ImportHashed [hash] :: ImportHashed -> Maybe SHA256Digest [importType] :: ImportHashed -> ImportType -- | How to interpret the import's contents (i.e. as Dhall code or raw -- text) data ImportMode Code :: ImportMode RawText :: ImportMode Location :: ImportMode -- | The type of import (i.e. local vs. remote vs. environment) data ImportType -- | Local path Local :: FilePrefix -> File -> ImportType -- | URL of remote resource and optional headers stored in an import Remote :: URL -> ImportType -- | Environment variable Env :: Text -> ImportType Missing :: ImportType -- | This type stores all of the components of a remote import data URL URL :: Scheme -> Text -> File -> Maybe Text -> Maybe (Expr Src Import) -> URL [scheme] :: URL -> Scheme [authority] :: URL -> Text [path] :: URL -> File [query] :: URL -> Maybe Text [headers] :: URL -> Maybe (Expr Src Import) -- | The URI scheme data Scheme HTTP :: Scheme HTTPS :: Scheme -- | This wrapper around Double exists for its Eq instance -- which is defined via the binary encoding of Dhall Doubles. newtype DhallDouble DhallDouble :: Double -> DhallDouble [getDhallDouble] :: DhallDouble -> Double -- | Label for a bound variable -- -- The Expr field is the variable's name (i.e. "x"). -- -- The Int field disambiguates variables with the same name if -- there are multiple bound variables of the same name in scope. Zero -- refers to the nearest bound variable and the index increases by one -- for each bound variable of the same name going outward. The following -- diagram may help: -- --
-- ┌──refers to──┐ -- │ │ -- v │ -- λ(x : Type) → λ(y : Type) → λ(x : Type) → x@0 -- -- ┌─────────────────refers to─────────────────┐ -- │ │ -- v │ -- λ(x : Type) → λ(y : Type) → λ(x : Type) → x@1 ---- -- This Int behaves like a De Bruijn index in the special case -- where all variables have the same name. -- -- You can optionally omit the index if it is 0: -- --
-- ┌─refers to─┐ -- │ │ -- v │ -- λ(x : Type) → λ(y : Type) → λ(x : Type) → x ---- -- Zero indices are omitted when pretty-printing Vars and non-zero -- indices appear as a numeric suffix. data Var V :: Text -> !Int -> Var -- | Record the binding part of a let expression. -- -- For example, > let x : Bool = True in x will be instantiated as -- follows: -- --
-- Const c ~ c --Const :: Const -> Expr s a -- |
-- Var (V x 0) ~ x -- Var (V x n) ~ x@n --Var :: Var -> Expr s a -- |
-- Lam x A b ~ λ(x : A) -> b --Lam :: Text -> Expr s a -> Expr s a -> Expr s a -- |
-- Pi "_" A B ~ A -> B -- Pi x A B ~ ∀(x : A) -> B --Pi :: Text -> Expr s a -> Expr s a -> Expr s a -- |
-- App f a ~ f a --App :: Expr s a -> Expr s a -> Expr s a -- |
-- Let (Binding _ x _ Nothing _ r) e ~ let x = r in e -- Let (Binding _ x _ (Just t ) _ r) e ~ let x : t = r in e ---- -- The difference between -- --
-- let x = a let y = b in e ---- -- and -- --
-- let x = a in let y = b in e ---- -- is only an additional Note around Let "y" … in -- the second example. -- -- See MultiLet for a representation of let-blocks that mirrors -- the source code more closely. Let :: Binding s a -> Expr s a -> Expr s a -- |
-- Annot x t ~ x : t --Annot :: Expr s a -> Expr s a -> Expr s a -- |
-- Bool ~ Bool --Bool :: Expr s a -- |
-- BoolLit b ~ b --BoolLit :: Bool -> Expr s a -- |
-- BoolAnd x y ~ x && y --BoolAnd :: Expr s a -> Expr s a -> Expr s a -- |
-- BoolOr x y ~ x || y --BoolOr :: Expr s a -> Expr s a -> Expr s a -- |
-- BoolEQ x y ~ x == y --BoolEQ :: Expr s a -> Expr s a -> Expr s a -- |
-- BoolNE x y ~ x != y --BoolNE :: Expr s a -> Expr s a -> Expr s a -- |
-- BoolIf x y z ~ if x then y else z --BoolIf :: Expr s a -> Expr s a -> Expr s a -> Expr s a -- |
-- Natural ~ Natural --Natural :: Expr s a -- |
-- NaturalLit n ~ n --NaturalLit :: Natural -> Expr s a -- |
-- NaturalFold ~ Natural/fold --NaturalFold :: Expr s a -- |
-- NaturalBuild ~ Natural/build --NaturalBuild :: Expr s a -- |
-- NaturalIsZero ~ Natural/isZero --NaturalIsZero :: Expr s a -- |
-- NaturalEven ~ Natural/even --NaturalEven :: Expr s a -- |
-- NaturalOdd ~ Natural/odd --NaturalOdd :: Expr s a -- |
-- NaturalToInteger ~ Natural/toInteger --NaturalToInteger :: Expr s a -- |
-- NaturalShow ~ Natural/show --NaturalShow :: Expr s a -- |
-- NaturalSubtract ~ Natural/subtract --NaturalSubtract :: Expr s a -- |
-- NaturalPlus x y ~ x + y --NaturalPlus :: Expr s a -> Expr s a -> Expr s a -- |
-- NaturalTimes x y ~ x * y --NaturalTimes :: Expr s a -> Expr s a -> Expr s a -- |
-- Integer ~ Integer --Integer :: Expr s a -- |
-- IntegerLit n ~ ±n --IntegerLit :: Integer -> Expr s a -- | IntegerClamp ~ Integer/clamp IntegerClamp :: Expr s a -- | IntegerNegate ~ Integer/negate IntegerNegate :: Expr s a -- |
-- IntegerShow ~ Integer/show --IntegerShow :: Expr s a -- |
-- IntegerToDouble ~ Integer/toDouble --IntegerToDouble :: Expr s a -- |
-- Double ~ Double --Double :: Expr s a -- |
-- DoubleLit n ~ n --DoubleLit :: DhallDouble -> Expr s a -- |
-- DoubleShow ~ Double/show --DoubleShow :: Expr s a -- |
-- Text ~ Text --Text :: Expr s a -- |
-- TextLit (Chunks [(t1, e1), (t2, e2)] t3) ~ "t1${e1}t2${e2}t3"
--
TextLit :: Chunks s a -> Expr s a
-- | -- TextAppend x y ~ x ++ y --TextAppend :: Expr s a -> Expr s a -> Expr s a -- |
-- TextShow ~ Text/show --TextShow :: Expr s a -- |
-- List ~ List --List :: Expr s a -- |
-- ListLit (Just t ) [] ~ [] : t -- ListLit Nothing [x, y, z] ~ [x, y, z] ---- -- Invariant: A non-empty list literal is always represented as -- ListLit Nothing xs. -- -- When an annotated, non-empty list literal is parsed, it is represented -- as -- --
-- Annot (ListLit Nothing [x, y, z]) t ~ [x, y, z] : t --ListLit :: Maybe (Expr s a) -> Seq (Expr s a) -> Expr s a -- |
-- ListAppend x y ~ x # y --ListAppend :: Expr s a -> Expr s a -> Expr s a -- |
-- ListBuild ~ List/build --ListBuild :: Expr s a -- |
-- ListFold ~ List/fold --ListFold :: Expr s a -- |
-- ListLength ~ List/length --ListLength :: Expr s a -- |
-- ListHead ~ List/head --ListHead :: Expr s a -- |
-- ListLast ~ List/last --ListLast :: Expr s a -- |
-- ListIndexed ~ List/indexed --ListIndexed :: Expr s a -- |
-- ListReverse ~ List/reverse --ListReverse :: Expr s a -- |
-- Optional ~ Optional --Optional :: Expr s a -- |
-- Some e ~ Some e --Some :: Expr s a -> Expr s a -- |
-- None ~ None --None :: Expr s a -- |
-- OptionalFold ~ Optional/fold --OptionalFold :: Expr s a -- |
-- OptionalBuild ~ Optional/build --OptionalBuild :: Expr s a -- |
-- Record [(k1, t1), (k2, t2)] ~ { k1 : t1, k2 : t1 }
--
Record :: Map Text (Expr s a) -> Expr s a
-- |
-- RecordLit [(k1, v1), (k2, v2)] ~ { k1 = v1, k2 = v2 }
--
RecordLit :: Map Text (Expr s a) -> Expr s a
-- | -- Union [(k1, Just t1), (k2, Nothing)] ~ < k1 : t1 | k2 > --Union :: Map Text (Maybe (Expr s a)) -> Expr s a -- |
-- Combine x y ~ x ∧ y --Combine :: Expr s a -> Expr s a -> Expr s a -- |
-- CombineTypes x y ~ x ⩓ y --CombineTypes :: Expr s a -> Expr s a -> Expr s a -- |
-- Prefer x y ~ x ⫽ y --Prefer :: Expr s a -> Expr s a -> Expr s a -- |
-- RecordCompletion x y ~ x::y --RecordCompletion :: Expr s a -> Expr s a -> Expr s a -- |
-- Merge x y (Just t ) ~ merge x y : t -- Merge x y Nothing ~ merge x y --Merge :: Expr s a -> Expr s a -> Maybe (Expr s a) -> Expr s a -- |
-- ToMap x (Just t) ~ toMap x : t -- ToMap x Nothing ~ toMap x --ToMap :: Expr s a -> Maybe (Expr s a) -> Expr s a -- |
-- Field e x ~ e.x --Field :: Expr s a -> Text -> Expr s a -- |
-- Project e (Left xs) ~ e.{ xs }
--
--
-- | > Project e (Right t) ~ e.(t)
Project :: Expr s a -> Either (Set Text) (Expr s a) -> Expr s a
-- | -- Assert e ~ assert : e --Assert :: Expr s a -> Expr s a -- |
-- Equivalent x y ~ x ≡ y --Equivalent :: Expr s a -> Expr s a -> Expr s a -- |
-- Note s x ~ e --Note :: s -> Expr s a -> Expr s a -- |
-- ImportAlt ~ e1 ? e2 --ImportAlt :: Expr s a -> Expr s a -> Expr s a -- |
-- Embed import ~ import --Embed :: a -> Expr s a -- | α-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 -- | 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 -- | 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 -- | 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) -- | An variation on NormalizerM for pure normalizers type Normalizer a = NormalizerM Identity 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)) -- | A reified Normalizer, which can be stored in structures without -- running into impredicative polymorphism. newtype ReifiedNormalizer a ReifiedNormalizer :: Normalizer a -> ReifiedNormalizer a [getReifiedNormalizer] :: ReifiedNormalizer a -> Normalizer a -- | 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 -- | 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 -- | 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: -- --
-- >>> "x" `freeIn` "x" -- True -- -- >>> "x" `freeIn` "y" -- False -- -- >>> "x" `freeIn` Lam "x" (Const Type) "x" -- False --freeIn :: Eq a => Var -> Expr s a -> Bool -- | Pretty-print a value pretty :: Pretty a => a -> Text -- | A traversal over the immediate sub-expressions of an expression. subExpressions :: Applicative f => (Expr s a -> f (Expr s a)) -> Expr s a -> f (Expr s a) -- | A traversal over the immediate sub-expressions in Chunks. chunkExprs :: Applicative f => (Expr s a -> f (Expr t b)) -> Chunks s a -> f (Chunks t b) -- | Traverse over the immediate Expr children in a Binding. bindingExprs :: Applicative f => (Expr s a -> f (Expr s b)) -> Binding s a -> f (Binding s b) -- | Generate a MultiLet from the contents of a Let. -- -- In the resulting MultiLet bs e, e is -- guaranteed not to be a Let, but it might be a (Note -- … (Let …)). -- -- Given parser output, multiLet consolidates lets that -- formed a let-block in the original source. multiLet :: Binding s a -> Expr s a -> MultiLet s a -- | Wrap let-Bindings around an Expr. -- -- wrapInLets can be understood as an inverse for multiLet: -- --
-- let MultiLet bs e1 = multiLet b e0 -- -- wrapInLets bs e1 == Let b e0 --wrapInLets :: Foldable f => f (Binding s a) -> Expr s a -> Expr s a -- | This type represents 1 or more nested Let bindings that have -- been coalesced together for ease of manipulation data MultiLet s a MultiLet :: NonEmpty (Binding s a) -> Expr s a -> MultiLet s a -- | Utility function used to throw internal errors that should never -- happen (in theory) but that are not enforced by the type system internalError :: Text -> forall b. b -- | The set of reserved identifiers for the Dhall language reservedIdentifiers :: HashSet Text -- | Escape a Expr literal using Dhall's escaping rules -- -- Note that the result does not include surrounding quotes escapeText :: Text -> Text -- | Returns True if the given Char is valid within an -- unquoted path component -- -- This is exported for reuse within the -- Dhall.Parser.Token module pathCharacter :: Char -> Bool -- | Convenience utility for converting Either-based exceptions to -- IO-based exceptions throws :: (Exception e, MonadIO io) => Either e a -> io a -- | Utility that powers the Text/show built-in textShow :: Text -> Text -- | Utility used to implement the --censor flag, by: -- --
-- -- Comment 1 -- 2 ---- -- Then this will preserve Comment 1, but not Comment 2 -- -- This is used by dhall-format to preserve leading comments and -- whitespace exprAndHeaderFromText :: String -> Text -> Either ParseError (Header, Expr Src Import) -- | Replace the source code with spaces when rendering error messages -- -- This utility is used to implement the --censor flag censor :: ParseError -> ParseError -- | Create a header with stripped leading spaces and trailing newlines createHeader :: Text -> Header -- | Parser for a top-level Dhall expression expr :: Parser (Expr Src Import) -- | Parser for a top-level Dhall expression. The expression is -- parameterized over any parseable type, allowing the language to be -- extended as needed. exprA :: Parser a -> Parser (Expr Src a) -- | 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 -> Header -- | Source code extract data Src Src :: !SourcePos -> !SourcePos -> Text -> Src [srcStart] :: Src -> !SourcePos [srcEnd] :: Src -> !SourcePos [srcText] :: Src -> Text -- | An exception annotated with a Src span data SourcedException e SourcedException :: Src -> e -> SourcedException e -- | A parsing error data ParseError ParseError :: ParseErrorBundle Text Void -> Text -> ParseError [unwrap] :: ParseError -> ParseErrorBundle Text Void [input] :: ParseError -> Text -- | A Parser that is almost identical to -- Text.Megaparsec.Parsec except treating -- Haskell-style comments as whitespace newtype Parser a Parser :: Parsec Void Text a -> Parser a [unParser] :: Parser a -> Parsec Void Text a instance GHC.Show.Show Dhall.Parser.Header instance GHC.Show.Show Dhall.Parser.ParseError instance GHC.Exception.Type.Exception Dhall.Parser.ParseError -- | This module contains the implementation of the dhall lint -- command module Dhall.Lint -- | Automatically improve a Dhall expression -- -- Currently this: -- --
-- >>> let x :: Either Void Int; x = Right 5
--
-- >>> :{
-- case x of
-- Right r -> r
-- Left l -> absurd l
-- :}
-- 5
--
absurd :: () => Void -> a
-- | A structured type error that includes context
data TypeError s a
TypeError :: Context (Expr s a) -> Expr s a -> TypeMessage s a -> TypeError s a
[context] :: TypeError s a -> Context (Expr s a)
[current] :: TypeError s a -> Expr s a
[typeMessage] :: TypeError s a -> TypeMessage s a
-- | Newtype used to wrap error messages so that they render with a more
-- detailed explanation of what went wrong
newtype DetailedTypeError s a
DetailedTypeError :: TypeError s a -> DetailedTypeError s a
-- | Wrap a type error in this exception type to censor source code and
-- Expr literals from the error message
data Censored
CensoredDetailed :: DetailedTypeError Src X -> Censored
Censored :: TypeError Src X -> Censored
-- | The specific type error
data TypeMessage s a
UnboundVariable :: Text -> TypeMessage s a
InvalidInputType :: Expr s a -> TypeMessage s a
InvalidOutputType :: Expr s a -> TypeMessage s a
NotAFunction :: Expr s a -> Expr s a -> TypeMessage s a
TypeMismatch :: Expr s a -> Expr s a -> Expr s a -> Expr s a -> TypeMessage s a
AnnotMismatch :: Expr s a -> Expr s a -> Expr s a -> TypeMessage s a
Untyped :: TypeMessage s a
MissingListType :: TypeMessage s a
MismatchedListElements :: Int -> Expr s a -> Expr s a -> Expr s a -> TypeMessage s a
InvalidListElement :: Int -> Expr s a -> Expr s a -> Expr s a -> TypeMessage s a
InvalidListType :: Expr s a -> TypeMessage s a
ListLitInvariant :: TypeMessage s a
InvalidSome :: Expr s a -> Expr s a -> Expr s a -> TypeMessage s a
InvalidPredicate :: Expr s a -> Expr s a -> TypeMessage s a
IfBranchMismatch :: Expr s a -> Expr s a -> Expr s a -> Expr s a -> TypeMessage s a
IfBranchMustBeTerm :: Bool -> Expr s a -> Expr s a -> Expr s a -> TypeMessage s a
InvalidFieldType :: Text -> Expr s a -> TypeMessage s a
InvalidAlternativeType :: Text -> Expr s a -> TypeMessage s a
AlternativeAnnotationMismatch :: Text -> Expr s a -> Const -> Text -> Expr s a -> Const -> TypeMessage s a
ListAppendMismatch :: Expr s a -> Expr s a -> TypeMessage s a
MustCombineARecord :: Char -> Expr s a -> Expr s a -> TypeMessage s a
InvalidRecordCompletion :: Text -> Expr s a -> TypeMessage s a
CompletionSchemaMustBeARecord :: Expr s a -> Expr s a -> TypeMessage s a
CombineTypesRequiresRecordType :: Expr s a -> Expr s a -> TypeMessage s a
RecordTypeMismatch :: Const -> Const -> Expr s a -> Expr s a -> TypeMessage s a
FieldCollision :: Text -> TypeMessage s a
MustMergeARecord :: Expr s a -> Expr s a -> TypeMessage s a
MustMergeUnion :: Expr s a -> Expr s a -> TypeMessage s a
MustMapARecord :: Expr s a -> Expr s a -> TypeMessage s a
InvalidToMapRecordKind :: Expr s a -> Expr s a -> TypeMessage s a
HeterogenousRecordToMap :: Expr s a -> Expr s a -> Expr s a -> TypeMessage s a
InvalidToMapType :: Expr s a -> TypeMessage s a
MapTypeMismatch :: Expr s a -> Expr s a -> TypeMessage s a
MissingToMapType :: TypeMessage s a
UnusedHandler :: Set Text -> TypeMessage s a
MissingHandler :: Text -> Set Text -> TypeMessage s a
HandlerInputTypeMismatch :: Text -> Expr s a -> Expr s a -> TypeMessage s a
DisallowedHandlerType :: Text -> Expr s a -> Expr s a -> Text -> TypeMessage s a
HandlerOutputTypeMismatch :: Text -> Expr s a -> Text -> Expr s a -> TypeMessage s a
InvalidHandlerOutputType :: Text -> Expr s a -> Expr s a -> TypeMessage s a
MissingMergeType :: TypeMessage s a
HandlerNotAFunction :: Text -> Expr s a -> TypeMessage s a
CantAccess :: Text -> Expr s a -> Expr s a -> TypeMessage s a
CantProject :: Text -> Expr s a -> Expr s a -> TypeMessage s a
CantProjectByExpression :: Expr s a -> TypeMessage s a
MissingField :: Text -> Expr s a -> TypeMessage s a
MissingConstructor :: Text -> Expr s a -> TypeMessage s a
ProjectionTypeMismatch :: Text -> Expr s a -> Expr s a -> Expr s a -> Expr s a -> TypeMessage s a
AssertionFailed :: Expr s a -> Expr s a -> TypeMessage s a
NotAnEquivalence :: Expr s a -> TypeMessage s a
IncomparableExpression :: Expr s a -> TypeMessage s a
EquivalenceTypeMismatch :: Expr s a -> Expr s a -> Expr s a -> Expr s a -> TypeMessage s a
CantAnd :: Expr s a -> Expr s a -> TypeMessage s a
CantOr :: Expr s a -> Expr s a -> TypeMessage s a
CantEQ :: Expr s a -> Expr s a -> TypeMessage s a
CantNE :: Expr s a -> Expr s a -> TypeMessage s a
CantInterpolate :: Expr s a -> Expr s a -> TypeMessage s a
CantTextAppend :: Expr s a -> Expr s a -> TypeMessage s a
CantListAppend :: Expr s a -> Expr s a -> TypeMessage s a
CantAdd :: Expr s a -> Expr s a -> TypeMessage s a
CantMultiply :: Expr s a -> Expr s a -> TypeMessage s a
instance (GHC.Show.Show s, GHC.Show.Show a) => GHC.Show.Show (Dhall.TypeCheck.TypeMessage s a)
instance GHC.Show.Show Dhall.TypeCheck.Censored
instance GHC.Exception.Type.Exception Dhall.TypeCheck.Censored
instance Data.Text.Prettyprint.Doc.Internal.Pretty Dhall.TypeCheck.Censored
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)
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)
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)
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)
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)
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)
-- | This module contains the implementation of the dhall tags
-- command
module Dhall.Tags
-- | Generate etags for Dhall expressions
generate :: Input -> Maybe [Text] -> Bool -> IO Text
instance GHC.Show.Show Dhall.Tags.Tag
instance GHC.Show.Show Dhall.Tags.LineOffset
instance GHC.Classes.Ord Dhall.Tags.LineOffset
instance GHC.Classes.Eq Dhall.Tags.LineOffset
instance GHC.Show.Show Dhall.Tags.LineColumn
instance GHC.Classes.Ord Dhall.Tags.LineColumn
instance GHC.Classes.Eq Dhall.Tags.LineColumn
instance GHC.Base.Semigroup Dhall.Tags.Tags
instance GHC.Base.Monoid Dhall.Tags.Tags
-- | Dhall lets you import external expressions located either in local
-- files or hosted on network endpoints.
--
-- To import a local file as an expression, just insert the path to the
-- file, prepending a ./ if the path is relative to the current
-- directory. For example, if you create a file named id with
-- the following contents:
--
-- -- $ cat id -- λ(a : Type) → λ(x : a) → x ---- -- Then you can use the file directly within a dhall program -- just by referencing the file's path: -- --
-- $ dhall -- ./id Bool True -- <Ctrl-D> -- Bool -- -- True ---- -- Imported expressions may contain imports of their own, too, which will -- continue to be resolved. However, Dhall will prevent cyclic imports. -- For example, if you had these two files: -- --
-- $ cat foo -- ./bar ---- --
-- $ cat bar -- ./foo ---- -- ... Dhall would throw the following exception if you tried to import -- foo: -- --
-- $ dhall -- ./foo -- ^D -- ↳ ./foo -- ↳ ./bar -- -- Cyclic import: ./foo ---- -- You can also import expressions hosted on network endpoints. Just use -- the URL -- --
-- http://host[:port]/path ---- -- The compiler expects the downloaded expressions to be in the same -- format as local files, specifically UTF8-encoded source code text. -- -- For example, if our id expression were hosted at -- http://example.com/id, then we would embed the -- expression within our code using: -- --
-- http://example.com/id ---- -- You can also import expressions stored within environment variables -- using env:NAME, where NAME is the name of the -- environment variable. For example: -- --
-- $ export FOO=1
-- $ export BAR='"Hi"'
-- $ export BAZ='λ(x : Bool) → x == False'
-- $ dhall <<< "{ foo = env:FOO , bar = env:BAR , baz = env:BAZ }"
-- { bar : Text, baz : ∀(x : Bool) → Bool, foo : Integer }
--
-- { bar = "Hi", baz = λ(x : Bool) → x == False, foo = 1 }
--
--
-- If you wish to import the raw contents of an impoert as Text
-- then add as Text to the end of the import:
--
--
-- $ dhall <<< "http://example.com as Text"
-- Text
--
-- "<!doctype html>\n<html>\n<head>\n <title>Example Domain</title>\n\n <meta
-- charset=\"utf-8\" />\n <meta http-equiv=\"Content-type\" content=\"text/html
-- ; charset=utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width,
-- initial-scale=1\" />\n <style type=\"text/css\">\n body {\n backgro
-- und-color: #f0f0f2;\n margin: 0;\n padding: 0;\n font-famil
-- y: \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n \n
-- }\n div {\n width: 600px;\n margin: 5em auto;\n paddi
-- ng: 50px;\n background-color: #fff;\n border-radius: 1em;\n }\n
-- a:link, a:visited {\n color: #38488f;\n text-decoration: none;
-- \n }\n @media (max-width: 700px) {\n body {\n background
-- -color: #fff;\n }\n div {\n width: auto;\n m
-- argin: 0 auto;\n border-radius: 0;\n padding: 1em;\n
-- }\n }\n </style> \n</head>\n\n<body>\n<div>\n <h1>Example Domain</
-- h1>\n <p>This domain is established to be used for illustrative examples in d
-- ocuments. You may use this\n domain in examples without prior coordination or
-- asking for permission.</p>\n <p><a href=\"http://www.iana.org/domains/exampl
-- e\">More information...</a></p>\n</div>\n</body>\n</html>\n"
--
module Dhall.Import
-- | Resolve all imports within an expression
load :: Expr Src Import -> IO (Expr Src Void)
-- | Resolve all imports within an expression, importing relative to the
-- given directory.
loadRelativeTo :: FilePath -> SemanticCacheMode -> Expr Src Import -> IO (Expr Src Void)
-- | Generalized version of load
--
-- You can configure the desired behavior through the initial
-- Status that you supply
loadWith :: Expr Src Import -> StateT Status IO (Expr Src Void)
-- | Construct the file path corresponding to a local import. If the import
-- is _relative_ then the resulting path is also relative.
localToPath :: MonadIO io => FilePrefix -> File -> io FilePath
-- | Hash a fully resolved expression
hashExpression :: Expr Void Void -> SHA256Digest
-- | Convenience utility to hash a fully resolved expression and return the
-- base-16 encoded hash with the sha256: prefix
--
-- 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 Void Void -> Text
-- | Ensure that the given expression is present in the semantic cache. The
-- given expression should be alpha-beta-normal.
writeExpressionToSemanticCache :: Expr Void Void -> IO ()
-- | Warn if no cache directory is available
warnAboutMissingCaches :: (MonadCatch m, Alternative m, MonadIO m) => m ()
-- | Assert than an expression is import-free
assertNoImports :: MonadIO io => Expr Src Import -> io (Expr Src Void)
-- | State threaded throughout the import process
data Status
Status :: NonEmpty Chained -> [Depends] -> Map Chained ImportSemantics -> Maybe Manager -> (URL -> StateT Status IO Text) -> Maybe (ReifiedNormalizer Void) -> Context (Expr Src Void) -> SemanticCacheMode -> Status
-- | Stack of Imports that we've imported along the way to get to
-- the current point
[_stack] :: Status -> NonEmpty Chained
-- | Graph of all the imports visited so far, represented by a list of
-- import dependencies.
[_graph] :: Status -> [Depends]
-- | Cache of imported expressions with their node id in order to avoid
-- importing the same expression twice with different values
[_cache] :: Status -> Map Chained ImportSemantics
-- | Used to cache the Manager when making multiple requests
[_manager] :: Status -> Maybe Manager
-- | The remote resolver, fetches the content at the given URL.
[_remote] :: Status -> URL -> StateT Status IO Text
[_normalizer] :: Status -> Maybe (ReifiedNormalizer Void)
[_startingContext] :: Status -> Context (Expr Src Void)
[_semanticCacheMode] :: Status -> SemanticCacheMode
-- | This enables or disables the semantic cache for imports protected by
-- integrity checks
data SemanticCacheMode
IgnoreSemanticCache :: SemanticCacheMode
UseSemanticCache :: SemanticCacheMode
-- | A fully chained import, i.e. if it contains a relative path
-- that path is relative to the current directory. If it is a remote
-- import with headers those are well-typed (either of type `List {
-- header : Text, value Text}` or `List { mapKey : Text, mapValue Text})`
-- and in normal form. These invariants are preserved by the API exposed
-- by Dhall.Import.
data Chained
-- | The underlying import
chainedImport :: Chained -> Import
-- | Given a Local import construct the corresponding unhashed
-- Chained import (interpreting relative path as relative to the
-- current directory).
chainedFromLocalHere :: FilePrefix -> File -> ImportMode -> Chained
-- | Adjust the import mode of a chained import
chainedChangeMode :: ImportMode -> Chained -> Chained
-- | Default starting Status, importing relative to the given
-- directory.
emptyStatus :: FilePath -> Status
-- | Lens from a Status to its _stack field
stack :: Functor f => LensLike' f Status (NonEmpty Chained)
-- | Lens from a Status to its _cache field
cache :: Functor f => LensLike' f Status (Map Chained ImportSemantics)
-- | parent imports (i.e. depends on) child
data Depends
Depends :: Chained -> Chained -> Depends
[parent] :: Depends -> Chained
[child] :: Depends -> Chained
-- | Lens from a Status to its _graph field
graph :: Functor f => LensLike' f Status [Depends]
-- | Lens from a Status to its _remote field
remote :: Functor f => LensLike' f Status (URL -> StateT Status IO Text)
-- | Given a well-typed (of type `List { header : Text, value Text }` or
-- `List { mapKey : Text, mapValue Text }`) headers expressions in normal
-- form construct the corresponding binary http headers; otherwise return
-- the empty list.
toHeaders :: Expr s a -> [HTTPHeader]
-- | Lens from a Status to its _normalizer field
normalizer :: Functor f => LensLike' f Status (Maybe (ReifiedNormalizer Void))
-- | Lens from a Status to its _startingContext field
startingContext :: Functor f => LensLike' f Status (Context (Expr Src Void))
-- | Chain imports, also typecheck and normalize headers if applicable.
chainImport :: Chained -> Import -> StateT Status IO Chained
-- | An import that has been fully interpeted
data ImportSemantics
-- | An import failed because of a cycle in the import graph
newtype Cycle
Cycle :: Import -> Cycle
-- | The offending cyclic import
[cyclicImport] :: Cycle -> Import
-- | Dhall tries to ensure that all expressions hosted on network endpoints
-- are weakly referentially transparent, meaning roughly that any two
-- clients will compile the exact same result given the same URL.
--
-- To be precise, a strong interpretaton of referential transparency
-- means that if you compiled a URL you could replace the expression
-- hosted at that URL with the compiled result. Let's call this "static
-- linking". Dhall (very intentionally) does not satisfy this stronger
-- interpretation of referential transparency since "statically linking"
-- an expression (i.e. permanently resolving all imports) means that the
-- expression will no longer update if its dependencies change.
--
-- In general, either interpretation of referential transparency is not
-- enforceable in a networked context since one can easily violate
-- referential transparency with a custom DNS, but Dhall can still try to
-- guard against common unintentional violations. To do this, Dhall
-- enforces that a non-local import may not reference a local import.
--
-- Local imports are defined as:
--
-- -- >>> input integer "+2" -- 2 -- -- >>> input (vector double) "[1.0, 2.0]" -- [1.0,2.0] ---- -- Use auto to automatically select which type to decode based on -- the inferred return type: -- --
-- >>> input auto "True" :: IO Bool -- True ---- -- This uses the settings from defaultInputSettings. input :: Decoder a -> Text -> IO a -- | Extend input with a root directory to resolve imports relative -- to, a file to mention in errors as the source, a custom typing -- context, and a custom normalization process. inputWithSettings :: InputSettings -> Decoder a -> Text -> IO a -- | Type-check and evaluate a Dhall program that is read from the -- file-system. -- -- This uses the settings from defaultEvaluateSettings. inputFile :: Decoder a -> FilePath -> IO a -- | Extend inputFile with a custom typing context and a custom -- normalization process. inputFileWithSettings :: EvaluateSettings -> Decoder a -> FilePath -> IO a -- | Similar to input, but without interpreting the Dhall -- Expr into a Haskell type. -- -- Uses the settings from defaultInputSettings. inputExpr :: Text -> IO (Expr Src Void) -- | Extend inputExpr with a root directory to resolve imports -- relative to, a file to mention in errors as the source, a custom -- typing context, and a custom normalization process. inputExprWithSettings :: InputSettings -> Text -> IO (Expr Src Void) -- | Access the directory to resolve imports relative to. rootDirectory :: Functor f => LensLike' f InputSettings FilePath -- | Access the name of the source to report locations from; this is only -- used in error messages, so it's okay if this is a best guess or -- something symbolic. sourceName :: Functor f => LensLike' f InputSettings FilePath -- | Access the starting context used for evaluation and type-checking. startingContext :: (Functor f, HasEvaluateSettings s) => LensLike' f s (Context (Expr Src Void)) -- | Access the custom normalizer. normalizer :: (Functor f, HasEvaluateSettings s) => LensLike' f s (Maybe (ReifiedNormalizer Void)) -- | Default input settings: resolves imports relative to . (the -- current working directory), report errors as coming from -- (input), and default evaluation settings from -- defaultEvaluateSettings. defaultInputSettings :: InputSettings data InputSettings -- | Default evaluation settings: no extra entries in the initial context, -- and no special normalizer behaviour. defaultEvaluateSettings :: EvaluateSettings data EvaluateSettings class HasEvaluateSettings s -- | Use this to provide more detailed error messages -- --
-- > input auto "True" :: IO Integer -- *** Exception: Error: Expression doesn't match annotation -- -- True : Integer -- -- (input):1:1 ---- --
-- > detailed (input auto "True") :: IO Integer -- *** Exception: Error: Expression doesn't match annotation -- -- Explanation: You can annotate an expression with its type or kind using the -- ❰:❱ symbol, like this: -- -- -- ┌───────┐ -- │ x : t │ ❰x❱ is an expression and ❰t❱ is the annotated type or kind of ❰x❱ -- └───────┘ -- -- The type checker verifies that the expression's type or kind matches the -- provided annotation -- -- For example, all of the following are valid annotations that the type checker -- accepts: -- -- -- ┌─────────────┐ -- │ 1 : Natural │ ❰1❱ is an expression that has type ❰Natural❱, so the type -- └─────────────┘ checker accepts the annotation -- -- -- ┌───────────────────────┐ -- │ Natural/even 2 : Bool │ ❰Natural/even 2❱ has type ❰Bool❱, so the type -- └───────────────────────┘ checker accepts the annotation -- -- -- ┌────────────────────┐ -- │ List : Type → Type │ ❰List❱ is an expression that has kind ❰Type → Type❱, -- └────────────────────┘ so the type checker accepts the annotation -- -- -- ┌──────────────────┐ -- │ List Text : Type │ ❰List Text❱ is an expression that has kind ❰Type❱, so -- └──────────────────┘ the type checker accepts the annotation -- -- -- However, the following annotations are not valid and the type checker will -- reject them: -- -- -- ┌──────────┐ -- │ 1 : Text │ The type checker rejects this because ❰1❱ does not have type -- └──────────┘ ❰Text❱ -- -- -- ┌─────────────┐ -- │ List : Type │ ❰List❱ does not have kind ❰Type❱ -- └─────────────┘ -- -- -- You or the interpreter annotated this expression: -- -- ↳ True -- -- ... with this type or kind: -- -- ↳ Integer -- -- ... but the inferred type or kind of the expression is actually: -- -- ↳ Bool -- -- Some common reasons why you might get this error: -- -- ● The Haskell Dhall interpreter implicitly inserts a top-level annotation -- matching the expected type -- -- For example, if you run the following Haskell code: -- -- -- ┌───────────────────────────────┐ -- │ >>> input auto "1" :: IO Text │ -- └───────────────────────────────┘ -- -- -- ... then the interpreter will actually type check the following annotated -- expression: -- -- -- ┌──────────┐ -- │ 1 : Text │ -- └──────────┘ -- -- -- ... and then type-checking will fail -- -- ──────────────────────────────────────────────────────────────────────────────── -- -- True : Integer -- -- (input):1:1 --detailed :: IO a -> IO a -- | A (Decoder a) represents a way to marshal a value of type -- 'a' from Dhall into Haskell -- -- You can produce Decoders either explicitly: -- --
-- example :: Decoder (Vector Text) -- example = vector text ---- -- ... or implicitly using auto: -- --
-- example :: Decoder (Vector Text) -- example = auto ---- -- You can consume Decoders using the input function: -- --
-- input :: Decoder a -> Text -> IO a --data Decoder a Decoder :: (Expr Src Void -> Extractor Src Void a) -> Expr Src Void -> Decoder a -- | Extracts Haskell value from the Dhall expression [extract] :: Decoder a -> Expr Src Void -> Extractor Src Void a -- | Dhall type of the Haskell value [expected] :: Decoder a -> Expr Src Void -- | The RecordDecoder applicative functor allows you to build a -- Decoder from a Dhall record. -- -- For example, let's take the following Haskell data type: -- --
-- >>> :{
-- data Project = Project
-- { projectName :: Text
-- , projectDescription :: Text
-- , projectStars :: Natural
-- }
-- :}
--
--
-- And assume that we have the following Dhall record that we would like
-- to parse as a Project:
--
--
-- { name =
-- "dhall-haskell"
-- , description =
-- "A configuration language guaranteed to terminate"
-- , stars =
-- 289
-- }
--
--
-- Our decoder has type Decoder Project, but we can't
-- build that out of any smaller decoders, as Decoders cannot be
-- combined (they are only Functors). However, we can use a
-- RecordDecoder to build a Decoder for Project:
--
--
-- >>> :{
-- project :: Decoder Project
-- project =
-- record
-- ( Project <$> field "name" strictText
-- <*> field "description" strictText
-- <*> field "stars" natural
-- )
-- :}
--
newtype RecordDecoder a
RecordDecoder :: Product (Const (Map Text (Expr Src Void))) (Compose ((->) (Expr Src Void)) (Extractor Src Void)) a -> RecordDecoder a
-- | The UnionDecoder monoid allows you to build a Decoder
-- from a Dhall union
--
-- For example, let's take the following Haskell data type:
--
--
-- >>> :{
-- data Status = Queued Natural
-- | Result Text
-- | Errored Text
-- :}
--
--
-- And assume that we have the following Dhall union that we would like
-- to parse as a Status:
--
-- -- < Result : Text -- | Queued : Natural -- | Errored : Text -- >.Result "Finish successfully" ---- -- Our decoder has type Decoder Status, but we can't -- build that out of any smaller decoders, as Decoders cannot be -- combined (they are only Functors). However, we can use a -- UnionDecoder to build a Decoder for Status: -- --
-- >>> :{
-- status :: Decoder Status
-- status = union
-- ( ( Queued <$> constructor "Queued" natural )
-- <> ( Result <$> constructor "Result" strictText )
-- <> ( Errored <$> constructor "Errored" strictText )
-- )
-- :}
--
newtype UnionDecoder a
UnionDecoder :: Compose (Map Text) Decoder a -> UnionDecoder a
-- | An (Encoder a) represents a way to marshal a value of type
-- 'a' from Haskell into Dhall
data Encoder a
Encoder :: (a -> Expr Src Void) -> Expr Src Void -> Encoder a
-- | Embeds a Haskell value as a Dhall expression
[embed] :: Encoder a -> a -> Expr Src Void
-- | Dhall type of the Haskell value
[declared] :: Encoder a -> Expr Src Void
-- | Any value that implements FromDhall can be automatically
-- decoded based on the inferred return type of input
--
--
-- >>> input auto "[1, 2, 3]" :: IO (Vector Natural)
-- [1,2,3]
--
-- >>> input auto "toMap { a = False, b = True }" :: IO (Map Text Bool)
-- fromList [("a",False),("b",True)]
--
--
-- This class auto-generates a default implementation for records that
-- implement Generic. This does not auto-generate an instance for
-- recursive types.
class FromDhall a
autoWith :: FromDhall a => InterpretOptions -> Decoder a
autoWith :: (FromDhall a, Generic a, GenericFromDhall (Rep a)) => InterpretOptions -> Decoder a
-- | A compatibility alias for FromDhall
--
-- This will eventually be removed.
type Interpret = FromDhall
-- | 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 Decoder was provided to
-- the input function
data InvalidDecoder s a
InvalidDecoder :: Expr s a -> Expr s a -> InvalidDecoder s a
[invalidDecoderExpected] :: InvalidDecoder s a -> Expr s a
[invalidDecoderExpression] :: InvalidDecoder s a -> Expr s a
-- | One or more errors returned from extracting a Dhall expression to a
-- Haskell expression
newtype ExtractErrors s a
ExtractErrors :: NonEmpty (ExtractError s a) -> ExtractErrors s a
[getErrors] :: ExtractErrors s a -> NonEmpty (ExtractError s a)
-- | Useful synonym for the Validation type used when marshalling
-- Dhall expressions
type Extractor s a = Validation (ExtractErrors s a)
-- | Useful synonym for the equivalent Either type used when
-- marshalling Dhall code
type MonadicExtractor s a = Either (ExtractErrors s a)
-- | Generate a type error during extraction by specifying the expected
-- type and the actual type
typeError :: Expr s a -> Expr s a -> Extractor s a b
-- | Turn a Expr message into an extraction failure
extractError :: Text -> Extractor s a b
-- | Switches from an Applicative extraction result, able to
-- accumulate errors, to a Monad extraction result, able to
-- chain sequential operations
toMonadic :: Extractor s a b -> MonadicExtractor s a b
-- | Switches from a Monad extraction result, able to chain
-- sequential errors, to an Applicative extraction result, able
-- to accumulate errors
fromMonadic :: MonadicExtractor s a b -> Extractor s a b
-- | Use the default options for interpreting a configuration file
--
-- -- auto = autoWith defaultInterpretOptions --auto :: FromDhall a => Decoder a -- | genericAuto is the default implementation for auto if -- you derive FromDhall. The difference is that you can use -- genericAuto without having to explicitly provide a -- FromDhall instance for a type as long as the type derives -- Generic genericAuto :: (Generic a, GenericFromDhall (Rep a)) => Decoder a -- | Use these options to tweak how Dhall derives a generic implementation -- of FromDhall data InterpretOptions InterpretOptions :: (Text -> Text) -> (Text -> Text) -> SingletonConstructors -> ReifiedNormalizer Void -> InterpretOptions -- | Function used to transform Haskell field names into their -- corresponding Dhall field names [fieldModifier] :: InterpretOptions -> Text -> Text -- | Function used to transform Haskell constructor names into their -- corresponding Dhall alternative names [constructorModifier] :: InterpretOptions -> Text -> Text -- | Specify how to handle constructors with only one field. The default is -- Wrapped for backwards compatibility but will eventually be -- changed to Smart [singletonConstructors] :: InterpretOptions -> SingletonConstructors -- | This is only used by the FromDhall instance for functions in -- order to normalize the function input before marshaling the input into -- a Dhall expression [inputNormalizer] :: InterpretOptions -> ReifiedNormalizer Void -- | This type specifies how to model a Haskell constructor with 1 field in -- Dhall -- -- For example, consider the following Haskell datatype definition: -- --
-- data Example = Foo { x :: Double } | Bar Double
--
--
-- Depending on which option you pick, the corresponding Dhall type could
-- be:
--
-- -- < Foo : Double | Bar : Double > -- Bare ---- --
-- < Foo : { x : Double } | Bar : { _1 : Double } > -- Wrapped
--
--
--
-- < Foo : { x : Double } | Bar : Double > -- Smart
--
data SingletonConstructors
-- | Never wrap the field in a record
Bare :: SingletonConstructors
-- | Always wrap the field in a record
Wrapped :: SingletonConstructors
-- | Only fields in a record if they are named
Smart :: SingletonConstructors
-- | Default interpret options, which you can tweak or override, like this:
--
--
-- autoWith
-- (defaultInterpretOptions { fieldModifier = Data.Text.Lazy.dropWhile (== '_') })
--
defaultInterpretOptions :: InterpretOptions
-- | Decode a Expr
--
-- -- >>> input bool "True" -- True --bool :: Decoder Bool -- | Decode a Expr -- --
-- >>> input natural "42" -- 42 --natural :: Decoder Natural -- | Decode an Expr -- --
-- >>> input integer "+42" -- 42 --integer :: Decoder Integer -- | Decode a Scientific -- --
-- >>> input scientific "1e100" -- 1.0e100 --scientific :: Decoder Scientific -- | Decode a Expr -- --
-- >>> input double "42.0" -- 42.0 --double :: Decoder Double -- | Decode lazy Expr -- --
-- >>> input lazyText "\"Test\"" -- "Test" --lazyText :: Decoder Text -- | Decode strict Expr -- --
-- >>> input strictText "\"Test\"" -- "Test" --strictText :: Decoder Text -- | Decode a Maybe -- --
-- >>> input (maybe natural) "Some 1" -- Just 1 --maybe :: Decoder a -> Decoder (Maybe a) -- | Decode a Seq -- --
-- >>> input (sequence natural) "[1, 2, 3]" -- fromList [1,2,3] --sequence :: Decoder a -> Decoder (Seq a) -- | Decode a list -- --
-- >>> input (list natural) "[1, 2, 3]" -- [1,2,3] --list :: Decoder a -> Decoder [a] -- | Decode a Vector -- --
-- >>> input (vector natural) "[1, 2, 3]" -- [1,2,3] --vector :: Decoder a -> Decoder (Vector a) -- | 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) -- | Decode a Set from a List with distinct elements -- --
-- >>> input (setFromDistinctList natural) "[1, 2, 3]" -- fromList [1,2,3] ---- -- An error is thrown if the list contains duplicates. -- --
-- >>> input (setFromDistinctList natural) "[1, 1, 3]" -- *** Exception: Error: Failed extraction -- -- The expression type-checked successfully but the transformation to the target -- type failed with the following error: -- -- One duplicate element in the list: 1 ---- --
-- >>> input (setFromDistinctList natural) "[1, 1, 3, 3]" -- *** Exception: Error: Failed extraction -- -- The expression type-checked successfully but the transformation to the target -- type failed with the following error: -- -- 2 duplicates were found in the list, including 1 --setFromDistinctList :: (Ord a, Show a) => Decoder a -> Decoder (Set a) -- | Decode a Set from a List -- --
-- >>> input (setIgnoringDuplicates natural) "[1, 2, 3]" -- fromList [1,2,3] ---- -- Duplicate elements are ignored. -- --
-- >>> input (setIgnoringDuplicates natural) "[1, 1, 3]" -- fromList [1,3] --setIgnoringDuplicates :: Ord a => Decoder a -> Decoder (Set a) -- | Decode a HashSet from a List with distinct elements -- --
-- >>> input (hashSetFromDistinctList natural) "[1, 2, 3]" -- fromList [1,2,3] ---- -- An error is thrown if the list contains duplicates. -- --
-- >>> input (hashSetFromDistinctList natural) "[1, 1, 3]" -- *** Exception: Error: Failed extraction -- -- The expression type-checked successfully but the transformation to the target -- type failed with the following error: -- -- One duplicate element in the list: 1 ---- --
-- >>> input (hashSetFromDistinctList natural) "[1, 1, 3, 3]" -- *** Exception: Error: Failed extraction -- -- The expression type-checked successfully but the transformation to the target -- type failed with the following error: -- -- 2 duplicates were found in the list, including 1 --hashSetFromDistinctList :: (Hashable a, Ord a, Show a) => Decoder a -> Decoder (HashSet a) -- | Decode a HashSet from a List -- --
-- >>> input (hashSetIgnoringDuplicates natural) "[1, 2, 3]" -- fromList [1,2,3] ---- -- Duplicate elements are ignored. -- --
-- >>> input (hashSetIgnoringDuplicates natural) "[1, 1, 3]" -- fromList [1,3] --hashSetIgnoringDuplicates :: (Hashable a, Ord a) => Decoder a -> Decoder (HashSet a) -- | Decode a Map from a toMap expression or generally a -- Prelude.Map.Type -- --
-- >>> input (Dhall.map strictText bool) "toMap { a = True, b = False }"
-- fromList [("a",True),("b",False)]
--
-- >>> input (Dhall.map strictText bool) "[ { mapKey = \"foo\", mapValue = True } ]"
-- fromList [("foo",True)]
--
--
-- If there are duplicate mapKeys, later mapValues take
-- precedence:
--
--
-- >>> let expr = "[ { mapKey = 1, mapValue = True }, { mapKey = 1, mapValue = False } ]"
--
-- >>> input (Dhall.map natural bool) expr
-- fromList [(1,False)]
--
map :: Ord k => Decoder k -> Decoder v -> Decoder (Map k v)
-- | Decode a HashMap from a toMap expression or generally
-- a Prelude.Map.Type
--
--
-- >>> input (Dhall.hashMap strictText bool) "toMap { a = True, b = False }"
-- fromList [("a",True),("b",False)]
--
-- >>> input (Dhall.hashMap strictText bool) "[ { mapKey = \"foo\", mapValue = True } ]"
-- fromList [("foo",True)]
--
--
-- If there are duplicate mapKeys, later mapValues take
-- precedence:
--
--
-- >>> let expr = "[ { mapKey = 1, mapValue = True }, { mapKey = 1, mapValue = False } ]"
--
-- >>> input (Dhall.hashMap natural bool) expr
-- fromList [(1,False)]
--
hashMap :: (Eq k, Hashable k) => Decoder k -> Decoder v -> Decoder (HashMap k v)
-- | Decode a tuple from a Prelude.Map.Entry record
--
--
-- >>> input (pairFromMapEntry strictText natural) "{ mapKey = \"foo\", mapValue = 3 }"
-- ("foo",3)
--
pairFromMapEntry :: Decoder k -> Decoder v -> Decoder (k, v)
-- | Decode () from an empty record.
--
--
-- >>> input unit "{=}" -- GHC doesn't print the result if it is ()
--
unit :: Decoder ()
-- | Decode Void from an empty union.
--
-- Since <> is uninhabited, input
-- void will always fail.
void :: Decoder Void
-- | Decode a String
--
-- -- >>> input string "\"ABC\"" -- "ABC" --string :: Decoder String -- | Given a pair of Decoders, decode a tuple-record into their -- pairing. -- --
-- >>> input (pair natural bool) "{ _1 = 42, _2 = False }"
-- (42,False)
--
pair :: Decoder a -> Decoder b -> Decoder (a, b)
-- | Run a RecordDecoder to build a Decoder.
record :: RecordDecoder a -> Decoder a
-- | Parse a single field of a record.
field :: Text -> Decoder a -> RecordDecoder a
-- | Run a UnionDecoder to build a Decoder.
union :: UnionDecoder a -> Decoder a
-- | Parse a single constructor of a union
constructor :: Text -> Decoder a -> UnionDecoder a
-- | This is the underlying class that powers the FromDhall class's
-- support for automatically deriving a generic implementation
class GenericFromDhall f
genericAutoWith :: GenericFromDhall f => InterpretOptions -> State Int (Decoder (f a))
-- | This is the underlying class that powers the FromDhall class's
-- support for automatically deriving a generic implementation
class GenericToDhall f
genericToDhallWith :: GenericToDhall f => InterpretOptions -> State Int (Encoder (f a))
-- | This class is used by FromDhall instance for functions:
--
-- -- instance (ToDhall a, FromDhall b) => FromDhall (a -> b) ---- -- You can convert Dhall functions with "simple" inputs (i.e. instances -- of this class) into Haskell functions. This works by: -- --
-- inject = injectWith defaultInterpretOptions --inject :: ToDhall a => Encoder a -- | Use the default options for injecting a value, whose structure is -- determined generically. -- -- This can be used when you want to use ToDhall on types that you -- don't want to define orphan instances for. genericToDhall :: (Generic a, GenericToDhall (Rep a)) => Encoder a -- | Intermediate type used for building a ToDhall instance for a -- record newtype RecordEncoder a RecordEncoder :: Map Text (Encoder a) -> RecordEncoder a -- | Specify how to encode one field of a record by supplying an explicit -- Encoder for that field encodeFieldWith :: Text -> Encoder a -> RecordEncoder a -- | Specify how to encode one field of a record using the default -- ToDhall instance for that type encodeField :: ToDhall a => Text -> RecordEncoder a -- | Convert a RecordEncoder into the equivalent Encoder recordEncoder :: RecordEncoder a -> Encoder a -- | UnionEncoder allows you to build an Encoder for a Dhall -- record. -- -- For example, let's take the following Haskell data type: -- --
-- >>> :{
-- data Status = Queued Natural
-- | Result Text
-- | Errored Text
-- :}
--
--
-- And assume that we have the following Dhall union that we would like
-- to parse as a Status:
--
-- -- < Result : Text -- | Queued : Natural -- | Errored : Text -- >.Result "Finish successfully" ---- -- Our encoder has type Encoder Status, but we can't -- build that out of any smaller encoders, as Encoders cannot be -- combined. However, we can use an UnionEncoder to build an -- Encoder for Status: -- --
-- >>> :{
-- injectStatus :: Encoder Status
-- injectStatus = adapt >$< unionEncoder
-- ( encodeConstructorWith "Queued" inject
-- >|< encodeConstructorWith "Result" inject
-- >|< encodeConstructorWith "Errored" inject
-- )
-- where
-- adapt (Queued n) = Left n
-- adapt (Result t) = Right (Left t)
-- adapt (Errored e) = Right (Right e)
-- :}
--
--
-- Or, since we are simply using the ToDhall instance to inject
-- each branch, we could write
--
--
-- >>> :{
-- injectStatus :: Encoder Status
-- injectStatus = adapt >$< unionEncoder
-- ( encodeConstructor "Queued"
-- >|< encodeConstructor "Result"
-- >|< encodeConstructor "Errored"
-- )
-- where
-- adapt (Queued n) = Left n
-- adapt (Result t) = Right (Left t)
-- adapt (Errored e) = Right (Right e)
-- :}
--
newtype UnionEncoder a
UnionEncoder :: Product (Const (Map Text (Expr Src Void))) (Op (Text, Expr Src Void)) a -> UnionEncoder a
-- | Specify how to encode an alternative by providing an explicit
-- Encoder for that alternative
encodeConstructorWith :: Text -> Encoder a -> UnionEncoder a
-- | Specify how to encode an alternative by using the default
-- ToDhall instance for that type
encodeConstructor :: ToDhall a => Text -> UnionEncoder a
-- | Convert a UnionEncoder into the equivalent Encoder
unionEncoder :: UnionEncoder a -> Encoder a
-- | Combines two UnionEncoder values. See UnionEncoder for
-- usage notes.
--
-- Ideally, this matches chosen; however, this allows
-- UnionEncoder to not need a Divisible instance itself
-- (since no instance is possible).
(>|<) :: UnionEncoder a -> UnionEncoder b -> UnionEncoder (Either a b)
infixr 5 >|<
-- | Use this function to extract Haskell values directly from Dhall AST.
-- The intended use case is to allow easy extraction of Dhall values for
-- making the function normalizeWith easier to use.
--
-- For other use cases, use input from Dhall module. It
-- will give you a much better user experience.
rawInput :: Alternative f => Decoder a -> Expr s Void -> f a
-- | This is an infix alias for contramap.
(>$<) :: Contravariant f => (a -> b) -> f b -> f a
infixl 4 >$<
-- | The RecordEncoder divisible (contravariant) functor allows you
-- to build an Encoder for a Dhall record.
--
-- For example, let's take the following Haskell data type:
--
--
-- >>> :{
-- data Project = Project
-- { projectName :: Text
-- , projectDescription :: Text
-- , projectStars :: Natural
-- }
-- :}
--
--
-- And assume that we have the following Dhall record that we would like
-- to parse as a Project:
--
--
-- { name =
-- "dhall-haskell"
-- , description =
-- "A configuration language guaranteed to terminate"
-- , stars =
-- 289
-- }
--
--
-- Our encoder has type Encoder Project, but we can't
-- build that out of any smaller encoders, as Encoders cannot be
-- combined (they are only Contravariants). However, we can use an
-- RecordEncoder to build an Encoder for Project:
--
--
-- >>> :{
-- injectProject :: Encoder Project
-- injectProject =
-- recordEncoder
-- ( adapt >$< encodeFieldWith "name" inject
-- >*< encodeFieldWith "description" inject
-- >*< encodeFieldWith "stars" inject
-- )
-- where
-- adapt (Project{..}) = (projectName, (projectDescription, projectStars))
-- :}
--
--
-- Or, since we are simply using the ToDhall instance to inject
-- each field, we could write
--
--
-- >>> :{
-- injectProject :: Encoder Project
-- injectProject =
-- recordEncoder
-- ( adapt >$< encodeField "name"
-- >*< encodeField "description"
-- >*< encodeField "stars"
-- )
-- where
-- adapt (Project{..}) = (projectName, (projectDescription, projectStars))
-- :}
--
--
-- Infix divided
(>*<) :: Divisible f => f a -> f b -> f (a, b)
infixr 5 >*<
-- | Type representing arbitrary-precision non-negative integers.
--
-- -- >>> 2^100 :: Natural -- 1267650600228229401496703205376 ---- -- Operations whose result would be negative throw -- (Underflow :: ArithException), -- --
-- >>> -1 :: Natural -- *** Exception: arithmetic underflow --data Natural -- | General-purpose finite sequences. data Seq a -- | A space efficient, packed, unboxed Unicode text type. data Text -- | Boxed vectors, supporting efficient slicing. data Vector a -- | Representable types of kind *. This class is derivable in GHC -- with the DeriveGeneric flag on. -- -- A Generic instance must satisfy the following laws: -- --
-- from . to ≡ id -- to . from ≡ id --class Generic a instance Data.Functor.Contravariant.Contravariant Dhall.UnionEncoder instance GHC.Base.Functor Dhall.UnionDecoder instance GHC.Base.Applicative Dhall.RecordDecoder instance GHC.Base.Functor Dhall.RecordDecoder instance GHC.Base.Functor Dhall.Decoder instance GHC.Base.Semigroup (Dhall.ExtractErrors s a) instance Data.Functor.Contravariant.Contravariant Dhall.RecordEncoder instance Data.Functor.Contravariant.Divisible.Divisible Dhall.RecordEncoder instance GHC.Base.Semigroup (Dhall.UnionDecoder a) instance GHC.Base.Monoid (Dhall.UnionDecoder a) instance (Dhall.ToDhall a, Dhall.FromDhall b) => Dhall.FromDhall (a -> b) instance Dhall.ToDhall Data.Void.Void instance Dhall.ToDhall GHC.Types.Bool instance Dhall.ToDhall Data.Text.Internal.Lazy.Text instance Dhall.ToDhall Data.Text.Internal.Text instance Dhall.ToDhall GHC.Base.String instance Dhall.ToDhall GHC.Natural.Natural instance Dhall.ToDhall GHC.Integer.Type.Integer instance Dhall.ToDhall GHC.Types.Int instance Dhall.ToDhall GHC.Types.Word instance Dhall.ToDhall GHC.Word.Word8 instance Dhall.ToDhall GHC.Word.Word16 instance Dhall.ToDhall GHC.Word.Word32 instance Dhall.ToDhall GHC.Word.Word64 instance Dhall.ToDhall GHC.Types.Double instance Dhall.ToDhall Data.Scientific.Scientific instance Dhall.ToDhall () instance Dhall.ToDhall a => Dhall.ToDhall (GHC.Maybe.Maybe a) instance Dhall.ToDhall a => Dhall.ToDhall (Data.Sequence.Internal.Seq a) instance Dhall.ToDhall a => Dhall.ToDhall [a] instance Dhall.ToDhall a => Dhall.ToDhall (Data.Vector.Vector a) instance Dhall.ToDhall a => Dhall.ToDhall (Data.Set.Internal.Set a) instance Dhall.ToDhall a => Dhall.ToDhall (Data.HashSet.Base.HashSet a) instance (Dhall.ToDhall a, Dhall.ToDhall b) => Dhall.ToDhall (a, b) instance (Dhall.ToDhall k, Dhall.ToDhall v) => Dhall.ToDhall (Data.Map.Internal.Map k v) instance (Dhall.ToDhall k, Dhall.ToDhall v) => Dhall.ToDhall (Data.HashMap.Base.HashMap k v) instance (GHC.Generics.Selector s, Dhall.ToDhall a) => Dhall.GenericToDhall (GHC.Generics.M1 GHC.Generics.S s (GHC.Generics.K1 i a)) instance forall k (f :: k -> *) (g :: k -> *) (s :: GHC.Generics.Meta) a i. (Dhall.GenericToDhall (f GHC.Generics.:*: g), GHC.Generics.Selector s, Dhall.ToDhall a) => Dhall.GenericToDhall ((f GHC.Generics.:*: g) GHC.Generics.:*: GHC.Generics.M1 GHC.Generics.S s (GHC.Generics.K1 i a)) instance forall k (s :: GHC.Generics.Meta) a (f :: k -> *) (g :: k -> *) i. (GHC.Generics.Selector s, Dhall.ToDhall a, Dhall.GenericToDhall (f GHC.Generics.:*: g)) => Dhall.GenericToDhall (GHC.Generics.M1 GHC.Generics.S s (GHC.Generics.K1 i a) GHC.Generics.:*: (f GHC.Generics.:*: g)) instance (GHC.Generics.Selector s1, GHC.Generics.Selector s2, Dhall.ToDhall a1, Dhall.ToDhall a2) => Dhall.GenericToDhall (GHC.Generics.M1 GHC.Generics.S s1 (GHC.Generics.K1 i1 a1) GHC.Generics.:*: GHC.Generics.M1 GHC.Generics.S s2 (GHC.Generics.K1 i2 a2)) instance forall k (f :: k -> *) (d :: GHC.Generics.Meta). Dhall.GenericToDhall f => Dhall.GenericToDhall (GHC.Generics.M1 GHC.Generics.D d f) instance forall k (f :: k -> *) (c :: GHC.Generics.Meta). Dhall.GenericToDhall f => Dhall.GenericToDhall (GHC.Generics.M1 GHC.Generics.C c f) instance forall k (c1 :: GHC.Generics.Meta) (c2 :: GHC.Generics.Meta) (f1 :: k -> *) (f2 :: k -> *). (GHC.Generics.Constructor c1, GHC.Generics.Constructor c2, Dhall.GenericToDhall f1, Dhall.GenericToDhall f2) => Dhall.GenericToDhall (GHC.Generics.M1 GHC.Generics.C c1 f1 GHC.Generics.:+: GHC.Generics.M1 GHC.Generics.C c2 f2) instance forall k (c :: GHC.Generics.Meta) (f :: k -> *) (g :: k -> *) (h :: k -> *). (GHC.Generics.Constructor c, Dhall.GenericToDhall (f GHC.Generics.:+: g), Dhall.GenericToDhall h) => Dhall.GenericToDhall ((f GHC.Generics.:+: g) GHC.Generics.:+: GHC.Generics.M1 GHC.Generics.C c h) instance forall k (c :: GHC.Generics.Meta) (f :: k -> *) (g :: k -> *) (h :: k -> *). (GHC.Generics.Constructor c, Dhall.GenericToDhall f, Dhall.GenericToDhall (g GHC.Generics.:+: h)) => Dhall.GenericToDhall (GHC.Generics.M1 GHC.Generics.C c f GHC.Generics.:+: (g GHC.Generics.:+: h)) instance forall k (f :: k -> *) (g :: k -> *) (h :: k -> *) (i :: k -> *). (Dhall.GenericToDhall (f GHC.Generics.:+: g), Dhall.GenericToDhall (h GHC.Generics.:+: i)) => Dhall.GenericToDhall ((f GHC.Generics.:+: g) GHC.Generics.:+: (h GHC.Generics.:+: i)) instance forall k (f :: k -> *) (g :: k -> *) (h :: k -> *) (i :: k -> *). (Dhall.GenericToDhall (f GHC.Generics.:*: g), Dhall.GenericToDhall (h GHC.Generics.:*: i)) => Dhall.GenericToDhall ((f GHC.Generics.:*: g) GHC.Generics.:*: (h GHC.Generics.:*: i)) instance Dhall.GenericToDhall GHC.Generics.U1 instance Data.Functor.Contravariant.Contravariant Dhall.Encoder instance Dhall.FromDhall Data.Void.Void instance Dhall.FromDhall () instance Dhall.FromDhall GHC.Types.Bool instance Dhall.FromDhall GHC.Natural.Natural instance Dhall.FromDhall GHC.Integer.Type.Integer instance Dhall.FromDhall Data.Scientific.Scientific instance Dhall.FromDhall GHC.Types.Double instance Dhall.FromDhall [GHC.Types.Char] instance Dhall.FromDhall Data.Text.Internal.Lazy.Text instance Dhall.FromDhall Data.Text.Internal.Text instance Dhall.FromDhall a => Dhall.FromDhall (GHC.Maybe.Maybe a) instance Dhall.FromDhall a => Dhall.FromDhall (Data.Sequence.Internal.Seq a) instance Dhall.FromDhall a => Dhall.FromDhall [a] instance Dhall.FromDhall a => Dhall.FromDhall (Data.Vector.Vector a) instance (Dhall.FromDhall a, GHC.Classes.Ord a, GHC.Show.Show a) => Dhall.FromDhall (Data.Set.Internal.Set a) instance (Dhall.FromDhall a, Data.Hashable.Class.Hashable a, GHC.Classes.Ord a, GHC.Show.Show a) => Dhall.FromDhall (Data.HashSet.Base.HashSet a) instance (GHC.Classes.Ord k, Dhall.FromDhall k, Dhall.FromDhall v) => Dhall.FromDhall (Data.Map.Internal.Map k v) instance (GHC.Classes.Eq k, Data.Hashable.Class.Hashable k, Dhall.FromDhall k, Dhall.FromDhall v) => Dhall.FromDhall (Data.HashMap.Base.HashMap k v) instance (Dhall.FromDhall a, Dhall.FromDhall b) => Dhall.FromDhall (a, b) instance Dhall.FromDhall (f (Dhall.Result f)) => Dhall.FromDhall (Dhall.Result f) instance (GHC.Base.Functor f, Dhall.FromDhall (f (Dhall.Result f))) => Dhall.FromDhall (Data.Fix.Fix f) instance forall k (f :: k -> *) (g :: k -> *) (s :: GHC.Generics.Meta) a i. (Dhall.GenericFromDhall (f GHC.Generics.:*: g), GHC.Generics.Selector s, Dhall.FromDhall a) => Dhall.GenericFromDhall ((f GHC.Generics.:*: g) GHC.Generics.:*: GHC.Generics.M1 GHC.Generics.S s (GHC.Generics.K1 i a)) instance forall k (s :: GHC.Generics.Meta) a (f :: k -> *) (g :: k -> *) i. (GHC.Generics.Selector s, Dhall.FromDhall a, Dhall.GenericFromDhall (f GHC.Generics.:*: g)) => Dhall.GenericFromDhall (GHC.Generics.M1 GHC.Generics.S s (GHC.Generics.K1 i a) GHC.Generics.:*: (f GHC.Generics.:*: g)) instance (GHC.Generics.Selector s1, GHC.Generics.Selector s2, Dhall.FromDhall a1, Dhall.FromDhall a2) => Dhall.GenericFromDhall (GHC.Generics.M1 GHC.Generics.S s1 (GHC.Generics.K1 i1 a1) GHC.Generics.:*: GHC.Generics.M1 GHC.Generics.S s2 (GHC.Generics.K1 i2 a2)) instance (GHC.Generics.Selector s, Dhall.FromDhall a) => Dhall.GenericFromDhall (GHC.Generics.M1 GHC.Generics.S s (GHC.Generics.K1 i a)) instance forall k (f :: k -> *) (d :: GHC.Generics.Meta). Dhall.GenericFromDhall f => Dhall.GenericFromDhall (GHC.Generics.M1 GHC.Generics.D d f) instance Dhall.GenericFromDhall GHC.Generics.V1 instance forall k (c1 :: GHC.Generics.Meta) (c2 :: GHC.Generics.Meta) (f1 :: k -> *) (f2 :: k -> *). (GHC.Generics.Constructor c1, GHC.Generics.Constructor c2, Dhall.GenericFromDhall f1, Dhall.GenericFromDhall f2) => Dhall.GenericFromDhall (GHC.Generics.M1 GHC.Generics.C c1 f1 GHC.Generics.:+: GHC.Generics.M1 GHC.Generics.C c2 f2) instance forall k (c :: GHC.Generics.Meta) (f :: k -> *) (g :: k -> *) (h :: k -> *). (GHC.Generics.Constructor c, Dhall.GenericFromDhall (f GHC.Generics.:+: g), Dhall.GenericFromDhall h) => Dhall.GenericFromDhall ((f GHC.Generics.:+: g) GHC.Generics.:+: GHC.Generics.M1 GHC.Generics.C c h) instance forall k (c :: GHC.Generics.Meta) (f :: k -> *) (g :: k -> *) (h :: k -> *). (GHC.Generics.Constructor c, Dhall.GenericFromDhall f, Dhall.GenericFromDhall (g GHC.Generics.:+: h)) => Dhall.GenericFromDhall (GHC.Generics.M1 GHC.Generics.C c f GHC.Generics.:+: (g GHC.Generics.:+: h)) instance forall k (f :: k -> *) (g :: k -> *) (h :: k -> *) (i :: k -> *). (Dhall.GenericFromDhall (f GHC.Generics.:+: g), Dhall.GenericFromDhall (h GHC.Generics.:+: i)) => Dhall.GenericFromDhall ((f GHC.Generics.:+: g) GHC.Generics.:+: (h GHC.Generics.:+: i)) instance forall k (f :: k -> *) (c :: GHC.Generics.Meta). Dhall.GenericFromDhall f => Dhall.GenericFromDhall (GHC.Generics.M1 GHC.Generics.C c f) instance Dhall.GenericFromDhall GHC.Generics.U1 instance forall k (f :: k -> *) (g :: k -> *) (h :: k -> *) (i :: k -> *). (Dhall.GenericFromDhall (f GHC.Generics.:*: g), Dhall.GenericFromDhall (h GHC.Generics.:*: i)) => Dhall.GenericFromDhall ((f GHC.Generics.:*: g) GHC.Generics.:*: (h GHC.Generics.:*: i)) instance Dhall.HasEvaluateSettings Dhall.InputSettings instance Dhall.HasEvaluateSettings Dhall.EvaluateSettings 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.ExtractErrors s a) 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.Exception.Type.Exception (Dhall.ExtractErrors s a) 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.ExtractError s a) 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.Exception.Type.Exception (Dhall.ExtractError s a) 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) 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 is a programming language specialized for configuration files. -- This module contains a tutorial explaining how to author configuration -- files using this language module Dhall.Tutorial -- | This module provides staticDhallExpression which can be used to -- resolve all of an expression’s imports at compile time, allowing one -- to reference Dhall expressions from Haskell without having a runtime -- dependency on the location of Dhall files. -- -- For example, given a file "./Some/Type.dhall" containing -- --
-- < This : Natural | Other : ../Other/Type.dhall > ---- -- ... rather than duplicating the AST manually in a Haskell Type, -- you can do: -- --
-- Dhall.Type -- (\case -- UnionLit "This" _ _ -> ... -- UnionLit "Other" _ _ -> ...) -- $(staticDhallExpression "./Some/Type.dhall") ---- -- This would create the Dhall Expr AST from the -- "./Some/Type.dhall" file at compile time with all imports -- resolved, making it easy to keep your Dhall configs and Haskell -- interpreters in sync. module Dhall.TH -- | This fully resolves, type checks, and normalizes the expression, so -- the resulting AST is self-contained. staticDhallExpression :: Text -> Q Exp -- | Utilities for getting the current version of the Haskell -- implementation of Dhall module Dhall.Version -- | The current Version of the Haskell implementation dhallVersion :: Version -- | The current version String for the Haskell implementation dhallVersionString :: String -- | This module contains the implementation of the dhall repl -- subcommand module Dhall.Repl -- | Implementation of the dhall repl subcommand repl :: CharacterSet -> Bool -> IO () -- | This module contains the top-level entrypoint and options parsing for -- the dhall executable module Dhall.Main -- | Top-level program options data Options Options :: Mode -> Bool -> Bool -> Bool -> Censor -> Options [mode] :: Options -> Mode [explain] :: Options -> Bool [plain] :: Options -> Bool [ascii] :: Options -> Bool [censor] :: Options -> Censor -- | The subcommands for the dhall executable data Mode Default :: Input -> Output -> Bool -> Bool -> SemanticCacheMode -> Bool -> Mode [file] :: Mode -> Input [output] :: Mode -> Output [annotate] :: Mode -> Bool [alpha] :: Mode -> Bool [semanticCacheMode] :: Mode -> SemanticCacheMode [version] :: Mode -> Bool Version :: Mode Resolve :: Input -> Maybe ResolveMode -> SemanticCacheMode -> Mode [file] :: Mode -> Input [resolveMode] :: Mode -> Maybe ResolveMode [semanticCacheMode] :: Mode -> SemanticCacheMode Type :: Input -> Bool -> SemanticCacheMode -> Mode [file] :: Mode -> Input [quiet] :: Mode -> Bool [semanticCacheMode] :: Mode -> SemanticCacheMode Normalize :: Input -> Bool -> Mode [file] :: Mode -> Input [alpha] :: Mode -> Bool Repl :: Mode Format :: FormatMode -> Mode [formatMode] :: Mode -> FormatMode Freeze :: Input -> Bool -> Bool -> Mode [inplace] :: Mode -> Input [all_] :: Mode -> Bool [cache] :: Mode -> Bool Hash :: Input -> Mode [file] :: Mode -> Input Diff :: Text -> Text -> Mode [expr1] :: Mode -> Text [expr2] :: Mode -> Text Lint :: Input -> Mode [inplace] :: Mode -> Input Tags :: Input -> Output -> Maybe [Text] -> Bool -> Mode [input] :: Mode -> Input [output] :: Mode -> Output [suffixes] :: Mode -> Maybe [Text] [followSymlinks] :: Mode -> Bool Encode :: Input -> Bool -> Mode [file] :: Mode -> Input [json] :: Mode -> Bool Decode :: Input -> Bool -> Mode [file] :: Mode -> Input [json] :: Mode -> Bool Text :: Input -> Mode [file] :: Mode -> Input SyntaxTree :: Input -> Mode [file] :: Mode -> Input -- | Parser for the Options type parseOptions :: Parser Options -- | ParserInfo for the Options type parserInfoOptions :: ParserInfo Options -- | Run the command specified by the Options type command :: Options -> IO () -- | Entry point for the dhall executable main :: IO ()