{-# LANGUAGE ConstraintKinds            #-}
{-# LANGUAGE DefaultSignatures          #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE FlexibleInstances          #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE RankNTypes                 #-}
{-# LANGUAGE RecordWildCards            #-}
{-# LANGUAGE ScopedTypeVariables        #-}
{-# LANGUAGE TupleSections              #-}
{-# LANGUAGE TypeApplications           #-}
{-# LANGUAGE TypeOperators              #-}
{-# LANGUAGE UndecidableInstances       #-}

{-| Please read the "Dhall.Tutorial" module, which contains a tutorial explaining
    how to use the language, the compiler, and this library
-}

module Dhall.Marshal.Encode
    ( -- * General
      Encoder(..)
    , ToDhall(..)
    , Inject
    , inject

      -- * Building encoders

      -- ** Records
    , RecordEncoder(..)
    , recordEncoder
    , encodeField
    , encodeFieldWith
      -- ** Unions
    , UnionEncoder(..)
    , unionEncoder
    , encodeConstructor
    , encodeConstructorWith
    , (>|<)

      -- * Generic encoding
    , GenericToDhall(..)
    , genericToDhall
    , genericToDhallWith
    , genericToDhallWithInputNormalizer
    , InterpretOptions(..)
    , SingletonConstructors(..)
    , defaultInterpretOptions

      -- * Miscellaneous
    , InputNormalizer(..)
    , defaultInputNormalizer
    , Result
    , (>$<)
    , (>*<)

    -- * Re-exports
    , Natural
    , Seq
    , Text
    , Vector
    , Generic
    ) where

import Control.Monad.Trans.State.Strict
import Data.Functor.Contravariant           (Contravariant (..), Op (..), (>$<))
import Data.Functor.Contravariant.Divisible (Divisible (..), divided)
import Dhall.Parser                         (Src (..))
import Dhall.Syntax
    ( Chunks (..)
    , DhallDouble (..)
    , Expr (..)
    )
import GHC.Generics
import Prelude                              hiding (maybe, sequence)

import qualified Control.Applicative
import qualified Data.ByteString
import qualified Data.ByteString.Lazy
import qualified Data.ByteString.Short
import qualified Data.Functor.Product
import qualified Data.HashMap.Strict   as HashMap
import qualified Data.HashSet
import qualified Data.Map
import qualified Data.Scientific
import qualified Data.Sequence
import qualified Data.Set
import qualified Data.Text
import qualified Data.Text.Lazy
import qualified Data.Text.Short
import qualified Data.Time             as Time
import qualified Data.Vector
import qualified Data.Void
import qualified Dhall.Core            as Core
import qualified Dhall.Map

import Dhall.Marshal.Internal

-- $setup
-- >>> :set -XRecordWildCards
-- >>> import Dhall.Pretty.Internal (prettyExpr)

{-| An @(Encoder a)@ represents a way to marshal a value of type @\'a\'@ from
    Haskell into Dhall.
-}
data Encoder a = Encoder
    { forall a. Encoder a -> a -> Expr Src Void
embed    :: a -> Expr Src Void
    -- ^ Embeds a Haskell value as a Dhall expression
    , forall a. Encoder a -> Expr Src Void
declared :: Expr Src Void
    -- ^ Dhall type of the Haskell value
    }

instance Contravariant Encoder where
    contramap :: forall a' a. (a' -> a) -> Encoder a -> Encoder a'
contramap a' -> a
f (Encoder a -> Expr Src Void
embed Expr Src Void
declared) = (a' -> Expr Src Void) -> Expr Src Void -> Encoder a'
forall a. (a -> Expr Src Void) -> Expr Src Void -> Encoder a
Encoder a' -> Expr Src Void
embed' Expr Src Void
declared
      where
        embed' :: a' -> Expr Src Void
embed' a'
x = a -> Expr Src Void
embed (a' -> a
f a'
x)

{-| This class is used by `Dhall.Marshal.Decode.FromDhall` instance for functions:

> instance (ToDhall a, FromDhall b) => FromDhall (a -> b)

    You can convert Dhall functions with "simple" inputs (i.e. instances of this
    class) into Haskell functions.  This works by:

    * Marshaling the input to the Haskell function into a Dhall expression (i.e.
      @x :: Expr Src Void@)
    * Applying the Dhall function (i.e. @f :: Expr Src Void@) to the Dhall input
      (i.e. @App f x@)
    * Normalizing the syntax tree (i.e. @normalize (App f x)@)
    * Marshaling the resulting Dhall expression back into a Haskell value

    This class auto-generates a default implementation for types that
    implement `Generic`.  This does not auto-generate an instance for recursive
    types.

    The default instance can be tweaked using 'genericToDhallWith'/'genericToDhallWithInputNormalizer'
    and custom 'InterpretOptions', or using
    [DerivingVia](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-DerivingVia)
    and 'Dhall.Deriving.Codec' from "Dhall.Deriving".
-}
class ToDhall a where
    injectWith :: InputNormalizer -> Encoder a
    default injectWith
        :: (Generic a, GenericToDhall (Rep a)) => InputNormalizer -> Encoder a
    injectWith InputNormalizer
_ = Encoder a
forall a. (Generic a, GenericToDhall (Rep a)) => Encoder a
genericToDhall

-- | A compatibility alias for `ToDhall`
type Inject = ToDhall
{-# DEPRECATED Inject "Use ToDhall instead" #-}

{-| Use the default input normalizer for injecting a value.

> inject = injectWith defaultInputNormalizer
-}
inject :: ToDhall a => Encoder a
inject :: forall a. ToDhall a => Encoder a
inject = InputNormalizer -> Encoder a
forall a. ToDhall a => InputNormalizer -> Encoder a
injectWith InputNormalizer
defaultInputNormalizer



instance ToDhall Void where
    injectWith :: InputNormalizer -> Encoder Void
injectWith InputNormalizer
_ = Encoder {Expr Src Void
Void -> Expr Src Void
forall {a}. Void -> a
forall {s} {a}. Expr s a
embed :: Void -> Expr Src Void
declared :: Expr Src Void
embed :: forall {a}. Void -> a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: Void -> a
embed = Void -> a
forall {a}. Void -> a
Data.Void.absurd

        declared :: Expr s a
declared = Map Text (Maybe (Expr s a)) -> Expr s a
forall s a. Map Text (Maybe (Expr s a)) -> Expr s a
Union Map Text (Maybe (Expr s a))
forall a. Monoid a => a
mempty

instance ToDhall Bool where
    injectWith :: InputNormalizer -> Encoder Bool
injectWith InputNormalizer
_ = Encoder {Expr Src Void
Bool -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. Bool -> Expr s a
embed :: Bool -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. Bool -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: Bool -> Expr s a
embed = Bool -> Expr s a
forall {s} {a}. Bool -> Expr s a
BoolLit

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Bool

instance ToDhall Data.ByteString.Short.ShortByteString where
    injectWith :: InputNormalizer -> Encoder ShortByteString
injectWith InputNormalizer
options =
        (ShortByteString -> ByteString)
-> Encoder ByteString -> Encoder ShortByteString
forall a' a. (a' -> a) -> Encoder a -> Encoder a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap ShortByteString -> ByteString
Data.ByteString.Short.fromShort (InputNormalizer -> Encoder ByteString
forall a. ToDhall a => InputNormalizer -> Encoder a
injectWith InputNormalizer
options)

instance ToDhall Data.ByteString.Lazy.ByteString where
    injectWith :: InputNormalizer -> Encoder ByteString
injectWith InputNormalizer
options =
        (ByteString -> ByteString)
-> Encoder ByteString -> Encoder ByteString
forall a' a. (a' -> a) -> Encoder a -> Encoder a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap ByteString -> ByteString
Data.ByteString.Lazy.toStrict (InputNormalizer -> Encoder ByteString
forall a. ToDhall a => InputNormalizer -> Encoder a
injectWith InputNormalizer
options)

instance ToDhall Data.ByteString.ByteString where
    injectWith :: InputNormalizer -> Encoder ByteString
injectWith InputNormalizer
_ = Encoder {Expr Src Void
ByteString -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. ByteString -> Expr s a
embed :: ByteString -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. ByteString -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: ByteString -> Expr s a
embed ByteString
bytes = ByteString -> Expr s a
forall {s} {a}. ByteString -> Expr s a
BytesLit ByteString
bytes

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Bytes

instance ToDhall Data.Text.Short.ShortText where
    injectWith :: InputNormalizer -> Encoder ShortText
injectWith InputNormalizer
_ = Encoder {Expr Src Void
ShortText -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. ShortText -> Expr s a
embed :: ShortText -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. ShortText -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: ShortText -> Expr s a
embed ShortText
text =
            Chunks s a -> Expr s a
forall s a. Chunks s a -> Expr s a
TextLit ([(Text, Expr s a)] -> Text -> Chunks s a
forall s a. [(Text, Expr s a)] -> Text -> Chunks s a
Chunks [] (ShortText -> Text
Data.Text.Short.toText ShortText
text))

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Text

instance ToDhall Data.Text.Lazy.Text where
    injectWith :: InputNormalizer -> Encoder Text
injectWith InputNormalizer
_ = Encoder {Expr Src Void
Text -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. Text -> Expr s a
embed :: Text -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. Text -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: Text -> Expr s a
embed Text
text =
            Chunks s a -> Expr s a
forall s a. Chunks s a -> Expr s a
TextLit ([(Text, Expr s a)] -> Text -> Chunks s a
forall s a. [(Text, Expr s a)] -> Text -> Chunks s a
Chunks [] (Text -> Text
Data.Text.Lazy.toStrict Text
text))

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Text

instance ToDhall Text where
    injectWith :: InputNormalizer -> Encoder Text
injectWith InputNormalizer
_ = Encoder {Expr Src Void
Text -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. Text -> Expr s a
embed :: Text -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. Text -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: Text -> Expr s a
embed Text
text = Chunks s a -> Expr s a
forall s a. Chunks s a -> Expr s a
TextLit ([(Text, Expr s a)] -> Text -> Chunks s a
forall s a. [(Text, Expr s a)] -> Text -> Chunks s a
Chunks [] Text
text)

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Text

instance {-# OVERLAPS #-} ToDhall String where
    injectWith :: InputNormalizer -> Encoder String
injectWith InputNormalizer
inputNormalizer =
        (String -> Text) -> Encoder Text -> Encoder String
forall a' a. (a' -> a) -> Encoder a -> Encoder a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap String -> Text
Data.Text.pack (InputNormalizer -> Encoder Text
forall a. ToDhall a => InputNormalizer -> Encoder a
injectWith InputNormalizer
inputNormalizer :: Encoder Text)

instance ToDhall Natural where
    injectWith :: InputNormalizer -> Encoder Natural
injectWith InputNormalizer
_ = Encoder {Expr Src Void
Natural -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. Natural -> Expr s a
embed :: Natural -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. Natural -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: Natural -> Expr s a
embed = Natural -> Expr s a
forall {s} {a}. Natural -> Expr s a
NaturalLit

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Natural

instance ToDhall Integer where
    injectWith :: InputNormalizer -> Encoder Integer
injectWith InputNormalizer
_ = Encoder {Expr Src Void
Integer -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. Integer -> Expr s a
embed :: Integer -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. Integer -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: Integer -> Expr s a
embed = Integer -> Expr s a
forall {s} {a}. Integer -> Expr s a
IntegerLit

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Integer

instance ToDhall Int where
    injectWith :: InputNormalizer -> Encoder Int
injectWith InputNormalizer
_ = Encoder {Expr Src Void
Int -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. Int -> Expr s a
embed :: Int -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. Int -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: Int -> Expr s a
embed = Integer -> Expr s a
forall {s} {a}. Integer -> Expr s a
IntegerLit (Integer -> Expr s a) -> (Int -> Integer) -> Int -> Expr s a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Integer
forall a. Integral a => a -> Integer
toInteger

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Integer

instance ToDhall Int8 where
    injectWith :: InputNormalizer -> Encoder Int8
injectWith InputNormalizer
_ = Encoder {Expr Src Void
Int8 -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. Int8 -> Expr s a
embed :: Int8 -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. Int8 -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: Int8 -> Expr s a
embed = Integer -> Expr s a
forall {s} {a}. Integer -> Expr s a
IntegerLit (Integer -> Expr s a) -> (Int8 -> Integer) -> Int8 -> Expr s a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int8 -> Integer
forall a. Integral a => a -> Integer
toInteger

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Integer

instance ToDhall Int16 where
    injectWith :: InputNormalizer -> Encoder Int16
injectWith InputNormalizer
_ = Encoder {Expr Src Void
Int16 -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. Int16 -> Expr s a
embed :: Int16 -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. Int16 -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: Int16 -> Expr s a
embed = Integer -> Expr s a
forall {s} {a}. Integer -> Expr s a
IntegerLit (Integer -> Expr s a) -> (Int16 -> Integer) -> Int16 -> Expr s a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int16 -> Integer
forall a. Integral a => a -> Integer
toInteger

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Integer

instance ToDhall Int32 where
    injectWith :: InputNormalizer -> Encoder Int32
injectWith InputNormalizer
_ = Encoder {Expr Src Void
Int32 -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. Int32 -> Expr s a
embed :: Int32 -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. Int32 -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: Int32 -> Expr s a
embed = Integer -> Expr s a
forall {s} {a}. Integer -> Expr s a
IntegerLit (Integer -> Expr s a) -> (Int32 -> Integer) -> Int32 -> Expr s a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> Integer
forall a. Integral a => a -> Integer
toInteger

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Integer

instance ToDhall Int64 where
    injectWith :: InputNormalizer -> Encoder Int64
injectWith InputNormalizer
_ = Encoder {Expr Src Void
Int64 -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. Int64 -> Expr s a
embed :: Int64 -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. Int64 -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: Int64 -> Expr s a
embed = Integer -> Expr s a
forall {s} {a}. Integer -> Expr s a
IntegerLit (Integer -> Expr s a) -> (Int64 -> Integer) -> Int64 -> Expr s a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> Integer
forall a. Integral a => a -> Integer
toInteger

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Integer

{-| Encode a 'Word' to a Dhall @Natural@.

>>> embed inject (12 :: Word)
NaturalLit 12
-}
instance ToDhall Word where
    injectWith :: InputNormalizer -> Encoder Word
injectWith InputNormalizer
_ = Encoder {Expr Src Void
Word -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. Word -> Expr s a
embed :: Word -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. Word -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: Word -> Expr s a
embed = Natural -> Expr s a
forall {s} {a}. Natural -> Expr s a
NaturalLit (Natural -> Expr s a) -> (Word -> Natural) -> Word -> Expr s a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word -> Natural
forall a b. (Integral a, Num b) => a -> b
fromIntegral

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Natural

{-| Encode a 'Word8' to a Dhall @Natural@.

>>> embed inject (12 :: Word8)
NaturalLit 12
-}
instance ToDhall Word8 where
    injectWith :: InputNormalizer -> Encoder Word8
injectWith InputNormalizer
_ = Encoder {Expr Src Void
Word8 -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. Word8 -> Expr s a
embed :: Word8 -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. Word8 -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: Word8 -> Expr s a
embed = Natural -> Expr s a
forall {s} {a}. Natural -> Expr s a
NaturalLit (Natural -> Expr s a) -> (Word8 -> Natural) -> Word8 -> Expr s a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Natural
forall a b. (Integral a, Num b) => a -> b
fromIntegral

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Natural

{-| Encode a 'Word16' to a Dhall @Natural@.

>>> embed inject (12 :: Word16)
NaturalLit 12
-}
instance ToDhall Word16 where
    injectWith :: InputNormalizer -> Encoder Word16
injectWith InputNormalizer
_ = Encoder {Expr Src Void
Word16 -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. Word16 -> Expr s a
embed :: Word16 -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. Word16 -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: Word16 -> Expr s a
embed = Natural -> Expr s a
forall {s} {a}. Natural -> Expr s a
NaturalLit (Natural -> Expr s a) -> (Word16 -> Natural) -> Word16 -> Expr s a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> Natural
forall a b. (Integral a, Num b) => a -> b
fromIntegral

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Natural

{-| Encode a 'Word32' to a Dhall @Natural@.

>>> embed inject (12 :: Word32)
NaturalLit 12
-}
instance ToDhall Word32 where
    injectWith :: InputNormalizer -> Encoder Word32
injectWith InputNormalizer
_ = Encoder {Expr Src Void
Word32 -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. Word32 -> Expr s a
embed :: Word32 -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. Word32 -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: Word32 -> Expr s a
embed = Natural -> Expr s a
forall {s} {a}. Natural -> Expr s a
NaturalLit (Natural -> Expr s a) -> (Word32 -> Natural) -> Word32 -> Expr s a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> Natural
forall a b. (Integral a, Num b) => a -> b
fromIntegral

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Natural

{-| Encode a 'Word64' to a Dhall @Natural@.

>>> embed inject (12 :: Word64)
NaturalLit 12
-}
instance ToDhall Word64 where
    injectWith :: InputNormalizer -> Encoder Word64
injectWith InputNormalizer
_ = Encoder {Expr Src Void
Word64 -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. Word64 -> Expr s a
embed :: Word64 -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. Word64 -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: Word64 -> Expr s a
embed = Natural -> Expr s a
forall {s} {a}. Natural -> Expr s a
NaturalLit (Natural -> Expr s a) -> (Word64 -> Natural) -> Word64 -> Expr s a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Natural
forall a b. (Integral a, Num b) => a -> b
fromIntegral

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Natural

instance ToDhall Double where
    injectWith :: InputNormalizer -> Encoder Double
injectWith InputNormalizer
_ = Encoder {Expr Src Void
Double -> Expr Src Void
forall {s} {a}. Expr s a
forall {s} {a}. Double -> Expr s a
embed :: Double -> Expr Src Void
declared :: Expr Src Void
embed :: forall {s} {a}. Double -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: Double -> Expr s a
embed = DhallDouble -> Expr s a
forall s a. DhallDouble -> Expr s a
DoubleLit (DhallDouble -> Expr s a)
-> (Double -> DhallDouble) -> Double -> Expr s a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> DhallDouble
DhallDouble

        declared :: Expr s a
declared = Expr s a
forall {s} {a}. Expr s a
Double

instance ToDhall Scientific where
    injectWith :: InputNormalizer -> Encoder Scientific
injectWith InputNormalizer
inputNormalizer =
        (Scientific -> Double) -> Encoder Double -> Encoder Scientific
forall a' a. (a' -> a) -> Encoder a -> Encoder a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap Scientific -> Double
forall a. RealFloat a => Scientific -> a
Data.Scientific.toRealFloat (InputNormalizer -> Encoder Double
forall a. ToDhall a => InputNormalizer -> Encoder a
injectWith InputNormalizer
inputNormalizer :: Encoder Double)

instance ToDhall () where
    injectWith :: InputNormalizer -> Encoder ()
injectWith InputNormalizer
_ = Encoder {Expr Src Void
() -> Expr Src Void
forall {s} {a}. Expr s a
forall {b} {s} {a}. b -> Expr s a
embed :: () -> Expr Src Void
declared :: Expr Src Void
embed :: forall {b} {s} {a}. b -> Expr s a
declared :: forall {s} {a}. Expr s a
..}
      where
        embed :: b -> Expr s a
embed = Expr s a -> b -> Expr s a
forall a b. a -> b -> a
const (Map Text (RecordField s a) -> Expr s a
forall s a. Map Text (RecordField s a) -> Expr s a
RecordLit Map Text (RecordField s a)
forall a. Monoid a => a
mempty)

        declared :: Expr s a
declared = Map Text (RecordField s a) -> Expr s a
forall s a. Map Text (RecordField s a) -> Expr s a
Record Map Text (RecordField s a)
forall a. Monoid a => a
mempty

instance ToDhall a => ToDhall (Maybe a) where
    injectWith :: InputNormalizer -> Encoder (Maybe a)
injectWith InputNormalizer
inputNormalizer = (Maybe a -> Expr Src Void) -> Expr Src Void -> Encoder (Maybe a)
forall a. (a -> Expr Src Void) -> Expr Src Void -> Encoder a
Encoder Maybe a -> Expr Src Void
embedOut Expr Src Void
declaredOut
      where
        embedOut :: Maybe a -> Expr Src Void
embedOut (Just a
x ) = Expr Src Void -> Expr Src Void
forall s a. Expr s a -> Expr s a
Some (a -> Expr Src Void
embedIn a
x)
        embedOut  Maybe a
Nothing  = Expr Src Void -> Expr Src Void -> Expr Src Void
forall s a. Expr s a -> Expr s a -> Expr s a
App Expr Src Void
forall {s} {a}. Expr s a
None Expr Src Void
declaredIn

        Encoder a -> Expr Src Void
embedIn Expr Src Void
declaredIn = InputNormalizer -> Encoder a
forall a. ToDhall a => InputNormalizer -> Encoder a
injectWith InputNormalizer
inputNormalizer

        declaredOut :: Expr Src Void
declaredOut = Expr Src Void -> Expr Src Void -> Expr Src Void
forall s a. Expr s a -> Expr s a -> Expr s a
App Expr Src Void
forall {s} {a}. Expr s a
Optional Expr Src Void
declaredIn

instance ToDhall a => ToDhall (Seq a) where
    injectWith :: InputNormalizer -> Encoder (Seq a)
injectWith InputNormalizer
inputNormalizer = (Seq a -> Expr Src Void) -> Expr Src Void -> Encoder (Seq a)
forall a. (a -> Expr Src Void) -> Expr Src Void -> Encoder a
Encoder Seq a -> Expr Src Void
embedOut Expr Src Void
declaredOut
      where
        embedOut :: Seq a -> Expr Src Void
embedOut Seq a
xs = Maybe (Expr Src Void) -> Seq (Expr Src Void) -> Expr Src Void
forall s a. Maybe (Expr s a) -> Seq (Expr s a) -> Expr s a
ListLit Maybe (Expr Src Void)
listType ((a -> Expr Src Void) -> Seq a -> Seq (Expr Src Void)
forall a b. (a -> b) -> Seq a -> Seq b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Expr Src Void
embedIn Seq a
xs)
          where
            listType :: Maybe (Expr Src Void)
listType
                | Seq a -> Bool
forall a. Seq a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Seq a
xs   = Expr Src Void -> Maybe (Expr Src Void)
forall a. a -> Maybe a