Safe Haskell | None |
---|---|
Language | Haskell98 |
Please read the Dhall.Tutorial module, which contains a tutorial explaining how to use the language, the compiler, and this library
- input :: Type a -> Text -> IO a
- inputWith :: Type a -> Context (Expr Src X) -> Normalizer X -> Text -> IO a
- detailed :: IO a -> IO a
- data Type a = Type {}
- data InputType a = InputType {}
- class Interpret a where
- data InvalidType = InvalidType
- auto :: Interpret a => Type a
- genericAuto :: (Generic a, GenericInterpret (Rep a)) => Type a
- data InterpretOptions = InterpretOptions {
- fieldModifier :: Text -> Text
- constructorModifier :: Text -> Text
- defaultInterpretOptions :: InterpretOptions
- bool :: Type Bool
- natural :: Type Natural
- integer :: Type Integer
- scientific :: Type Scientific
- double :: Type Double
- lazyText :: Type Text
- strictText :: Type Text
- maybe :: Type a -> Type (Maybe a)
- sequence :: Type a -> Type (Seq a)
- list :: Type a -> Type [a]
- vector :: Type a -> Type (Vector a)
- unit :: Type ()
- string :: Type String
- pair :: Type a -> Type b -> Type (a, b)
- class GenericInterpret f where
- class GenericInject f where
- class Inject a where
- inject :: Inject a => InputType a
- rawInput :: Alternative f => Type a -> Expr s X -> f a
- data Natural :: *
- data Seq a :: * -> *
- data Text :: *
- data Vector a :: * -> *
- class Generic a
Input
:: Type a | The type of value to decode from Dhall to Haskell |
-> Text | The Dhall program |
-> IO a | The decoded value in Haskell |
Type-check and evaluate a Dhall program, decoding the result into Haskell
The first argument determines the type of value that you decode:
>>>
input integer "2"
2>>>
input (vector double) "[1.0, 2.0]"
[1.0,2.0]
Use auto
to automatically select which type to decode based on the
inferred return type:
>>>
input auto "True" :: IO Bool
True
:: Type a | The type of value to decode from Dhall to Haskell |
-> Context (Expr Src X) | The starting context for type-checking |
-> Normalizer X | |
-> Text | The Dhall program |
-> IO a | The decoded value in Haskell |
Extend input
with a custom typing context and normalization process.
detailed :: IO a -> IO a Source #
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 : Integer │ ❰1❱ is an expression that has type ❰Integer❱, 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
Types
A (Type a)
represents a way to marshal a value of type 'a'
from Dhall
into Haskell
You can produce Type
s either explicitly:
example :: Type (Vector Text) example = vector text
... or implicitly using auto
:
example :: Type (Vector Text) example = auto
You can consume Type
s using the input
function:
input :: Type a -> Text -> IO a
An (InputType a)
represents a way to marshal a value of type 'a'
from
Haskell into Dhall
class Interpret a where Source #
Any value that implements Interpret
can be automatically decoded based on
the inferred return type of input
>>>
input auto "[1, 2, 3]" :: IO (Vector Integer)
[1,2,3]
This class auto-generates a default implementation for records that
implement Generic
. This does not auto-generate an instance for recursive
types.
autoWith :: InterpretOptions -> Type a Source #
autoWith :: (Generic a, GenericInterpret (Rep a)) => InterpretOptions -> Type a Source #
Interpret Bool Source # | |
Interpret Double Source # | |
Interpret Integer Source # | |
Interpret Natural Source # | |
Interpret Scientific Source # | |
Interpret Text Source # | |
Interpret Text Source # | |
Interpret [Char] Source # | |
Interpret a => Interpret [a] Source # | |
Interpret a => Interpret (Maybe a) Source # | |
Interpret a => Interpret (Seq a) Source # | |
Interpret a => Interpret (Vector a) Source # | |
(Inject a, Interpret b) => Interpret (a -> b) Source # | |
(Interpret a, Interpret b) => Interpret (a, b) Source # | |
data InvalidType Source #
auto :: Interpret a => Type a Source #
Use the default options for interpreting a configuration file
auto = autoWith defaultInterpretOptions
genericAuto :: (Generic a, GenericInterpret (Rep a)) => Type a Source #
genericAuto
is the default implementation for auto
if you derive
Interpret
. The difference is that you can use genericAuto
without
having to explicitly provide an Interpret
instance for a type as long as
the type derives Generic
data InterpretOptions Source #
Use these options to tweak how Dhall derives a generic implementation of
Interpret
InterpretOptions | |
|
defaultInterpretOptions :: InterpretOptions Source #
Default interpret options, which you can tweak or override, like this:
autoWith (defaultInterpretOptions { fieldModifier = Data.Text.Lazy.dropWhile (== '_') })
scientific :: Type Scientific Source #
Decode a Scientific
>>>
input scientific "1e1000000000"
1.0e1000000000
maybe :: Type a -> Type (Maybe a) Source #
Decode a Maybe
>>>
input (maybe integer) "[1] : Optional Integer"
Just 1
sequence :: Type a -> Type (Seq a) Source #
Decode a Seq
-
>>> input (sequence integer) "[1, 2, 3]"
[1,2,3]
vector :: Type a -> Type (Vector a) Source #
Decode a Vector
>>>
input (vector integer) "[1, 2, 3]"
[1,2,3]
pair :: Type a -> Type b -> Type (a, b) Source #
Given a pair of Type
s, decode a tuple-record into their pairing.
>>>
input (pair natural bool) "{ _1 = +42, _2 = False }"
(42, False)
class GenericInterpret f where Source #
This is the underlying class that powers the Interpret
class's support
for automatically deriving a generic implementation
genericAutoWith :: InterpretOptions -> State Int (Type (f a)) Source #
GenericInterpret (V1 *) Source # | |
GenericInterpret (U1 *) Source # | |
(Constructor Meta c, GenericInterpret f, GenericInterpret ((:+:) * g h)) => GenericInterpret ((:+:) * (M1 * C c f) ((:+:) * g h)) Source # | |
(Constructor Meta c1, Constructor Meta c2, GenericInterpret f1, GenericInterpret f2) => GenericInterpret ((:+:) * (M1 * C c1 f1) (M1 * C c2 f2)) Source # | |
(GenericInterpret ((:+:) * f g), GenericInterpret ((:+:) * h i)) => GenericInterpret ((:+:) * ((:+:) * f g) ((:+:) * h i)) Source # | |
(Constructor Meta c, GenericInterpret ((:+:) * f g), GenericInterpret h) => GenericInterpret ((:+:) * ((:+:) * f g) (M1 * C c h)) Source # | |
(GenericInterpret f, GenericInterpret g) => GenericInterpret ((:*:) * f g) Source # | |
GenericInterpret f => GenericInterpret (M1 * D d f) Source # | |
GenericInterpret f => GenericInterpret (M1 * C c f) Source # | |
(Selector Meta s, Interpret a) => GenericInterpret (M1 * S s (K1 * i a)) Source # | |
class GenericInject f where Source #
This is the underlying class that powers the Interpret
class's support
for automatically deriving a generic implementation
genericInjectWith :: InterpretOptions -> State Int (InputType (f a)) Source #
GenericInject (U1 *) Source # | |
(Constructor Meta c, GenericInject f, GenericInject ((:+:) * g h)) => GenericInject ((:+:) * (M1 * C c f) ((:+:) * g h)) Source # | |
(Constructor Meta c1, Constructor Meta c2, GenericInject f1, GenericInject f2) => GenericInject ((:+:) * (M1 * C c1 f1) (M1 * C c2 f2)) Source # | |
(GenericInject ((:+:) * f g), GenericInject ((:+:) * h i)) => GenericInject ((:+:) * ((:+:) * f g) ((:+:) * h i)) Source # | |
(Constructor Meta c, GenericInject ((:+:) * f g), GenericInject h) => GenericInject ((:+:) * ((:+:) * f g) (M1 * C c h)) Source # | |
(GenericInject f, GenericInject g) => GenericInject ((:*:) * f g) Source # | |
GenericInject f => GenericInject (M1 * D d f) Source # | |
GenericInject f => GenericInject (M1 * C c f) Source # | |
(Selector Meta s, Inject a) => GenericInject (M1 * S s (K1 * i a)) Source # | |
This class is used by Interpret
instance for functions:
instance (Inject a, Interpret b) => Interpret (a -> b)
You can convert Dhall functions with "simple" inputs (i.e. instances of this class) into Haskell functions. This works by:
- Marshaling the input to the Haskell function into a Dhall expression (i.e.
x :: Expr Src X
) - Applying the Dhall function (i.e.
f :: Expr Src X
) to the Dhall input (i.e.App f x
) - Normalizing the syntax tree (i.e.
normalize (App f x)
) - Marshaling the resulting Dhall expression back into a Haskell value
injectWith :: InterpretOptions -> InputType a Source #
injectWith :: (Generic a, GenericInject (Rep a)) => InterpretOptions -> InputType a Source #
Inject Bool Source # | |
Inject Double Source # | |
Inject Int Source # | |
Inject Integer Source # | |
Inject Natural Source # | |
Inject Word8 Source # | |
Inject Word16 Source # | |
Inject Word32 Source # | |
Inject Word64 Source # | |
Inject () Source # | |
Inject Scientific Source # | |
Inject Text Source # | |
Inject Text Source # | |
Inject a => Inject [a] Source # | |
Inject a => Inject (Maybe a) Source # | |
Inject a => Inject (Seq a) Source # | |
Inject a => Inject (Set a) Source # | |
Inject a => Inject (Vector a) Source # | |
(Inject a, Inject b) => Inject (a, b) Source # | |
inject :: Inject a => InputType a Source #
Use the default options for injecting a value
inject = inject defaultInterpretOptions
Miscellaneous
:: Alternative f | |
=> Type a | The type of value to decode from Dhall to Haskell |
-> Expr s X | a closed form Dhall program, which evaluates to the expected type |
-> f a | The decoded value in Haskell |
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.
Re-exports
Type representing arbitrary-precision non-negative integers.
Operations whose result would be negative
.throw
(Underflow
:: ArithException
)
Since: 4.8.0.0
Enum Natural | Since: 4.8.0.0 |
Eq Natural | |
Integral Natural | Since: 4.8.0.0 |
Num Natural | Since: 4.8.0.0 |
Ord Natural | |
Read Natural | Since: 4.8.0.0 |
Real Natural | Since: 4.8.0.0 |
Show Natural | Since: 4.8.0.0 |
Ix Natural | Since: 4.8.0.0 |
Lift Natural | |
Hashable Natural | |
Bits Natural | Since: 4.8.0.0 |
Subtractive Natural | |
Pretty Natural | |
Inject Natural Source # | |
Interpret Natural Source # | |
type Difference Natural | |
General-purpose finite sequences.
Monad Seq | |
Functor Seq | |
Applicative Seq | |
Foldable Seq | |
Traversable Seq | |
Alternative Seq | |
MonadPlus Seq | |
Eq1 Seq | |
Ord1 Seq | |
Read1 Seq | |
Show1 Seq | |
MonadZip Seq | |
UnzipWith Seq | |
IsList (Seq a) | |
Eq a => Eq (Seq a) | |
Data a => Data (Seq a) | |
Ord a => Ord (Seq a) | |
Read a => Read (Seq a) | |
Show a => Show (Seq a) | |
IsString (Seq Char) | |
Semigroup (Seq a) | |
Monoid (Seq a) | |
NFData a => NFData (Seq a) | |
Ixed (Seq a) | |
Wrapped (Seq a) | |
Inject a => Inject (Seq a) Source # | |
Interpret a => Interpret (Seq a) Source # | |
(~) * t (Seq a') => Rewrapped (Seq a) t | |
type Item (Seq a) | |
type Index (Seq a) | |
type IxValue (Seq a) | |
type Unwrapped (Seq a) | |
Boxed vectors, supporting efficient slicing.
Monad Vector | |
Functor Vector | |
Applicative Vector | |
Foldable Vector | |
Traversable Vector | |
Alternative Vector | |
MonadPlus Vector | |
Eq1 Vector | |
Ord1 Vector | |
Read1 Vector | |
Show1 Vector | |
MonadZip Vector | |
Vector Vector a | |
IsList (Vector a) | |
Eq a => Eq (Vector a) | |
Data a => Data (Vector a) | |
Ord a => Ord (Vector a) | |
Read a => Read (Vector a) | |
Show a => Show (Vector a) | |
Semigroup (Vector a) | |
Monoid (Vector a) | |
NFData a => NFData (Vector a) | |
Ixed (Vector a) | |
Wrapped (Vector a) | |
Inject a => Inject (Vector a) Source # | |
Interpret a => Interpret (Vector a) Source # | |
(~) * t (Vector a') => Rewrapped (Vector a) t | |
type Mutable Vector | |
type Item (Vector a) | |
type Index (Vector a) | |
type IxValue (Vector a) | |
type Unwrapped (Vector a) | |
Representable types of kind *. This class is derivable in GHC with the DeriveGeneric flag on.