2016-09-09 18:17:25 +02:00
|
|
|
{-# LANGUAGE DefaultSignatures #-}
|
|
|
|
{-# LANGUAGE DeriveFunctor #-}
|
|
|
|
{-# LANGUAGE FlexibleInstances #-}
|
|
|
|
{-# LANGUAGE FlexibleContexts #-}
|
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
2017-02-05 19:31:03 +01:00
|
|
|
{-# LANGUAGE QuasiQuotes #-}
|
2016-09-09 18:17:25 +02:00
|
|
|
{-# LANGUAGE RecordWildCards #-}
|
|
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
|
|
|
{-# LANGUAGE TypeOperators #-}
|
|
|
|
|
2016-11-25 04:15:29 +01:00
|
|
|
{-| Please read the "Dhall.Tutorial" module, which contains a tutorial explaining
|
|
|
|
how to use the language, the compiler, and this library
|
|
|
|
-}
|
2016-09-09 18:17:25 +02:00
|
|
|
|
|
|
|
module Dhall
|
|
|
|
(
|
|
|
|
-- * Input
|
|
|
|
input
|
2016-11-21 01:25:55 +01:00
|
|
|
, detailed
|
2016-09-09 18:17:25 +02:00
|
|
|
|
|
|
|
-- * Types
|
|
|
|
, Type
|
2016-09-13 06:27:47 +02:00
|
|
|
, Interpret(..)
|
2017-02-05 19:32:32 +01:00
|
|
|
, InvalidType(..)
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
, auto
|
2017-02-23 18:35:52 +01:00
|
|
|
, InterpretOptions(..)
|
|
|
|
, defaultInterpretOptions
|
2016-09-09 18:51:31 +02:00
|
|
|
, bool
|
2016-09-09 18:17:25 +02:00
|
|
|
, natural
|
|
|
|
, integer
|
|
|
|
, double
|
|
|
|
, text
|
2016-09-19 00:38:36 +02:00
|
|
|
, maybe
|
2016-09-09 18:17:25 +02:00
|
|
|
, vector
|
2017-02-23 18:35:52 +01:00
|
|
|
, GenericInterpret(..)
|
2016-09-09 18:17:25 +02:00
|
|
|
|
|
|
|
-- * Re-exports
|
2016-11-25 07:13:36 +01:00
|
|
|
, Natural
|
2016-09-19 00:24:54 +02:00
|
|
|
, Text
|
2016-09-09 18:17:25 +02:00
|
|
|
, Vector
|
|
|
|
, Generic
|
|
|
|
) where
|
|
|
|
|
2016-10-16 02:35:51 +02:00
|
|
|
import Control.Applicative (empty, liftA2, (<|>))
|
2016-09-09 18:17:25 +02:00
|
|
|
import Control.Exception (Exception)
|
2016-11-05 16:36:16 +01:00
|
|
|
import Data.Monoid ((<>))
|
2016-12-05 00:19:01 +01:00
|
|
|
import Data.Text.Buildable (Buildable(..))
|
2016-09-09 18:17:25 +02:00
|
|
|
import Data.Text.Lazy (Text)
|
2017-02-05 19:31:03 +01:00
|
|
|
import Data.Typeable (Typeable)
|
2016-09-09 18:17:25 +02:00
|
|
|
import Data.Vector (Vector)
|
2016-10-18 18:18:01 +02:00
|
|
|
import Dhall.Core (Expr(..))
|
2016-11-21 01:25:55 +01:00
|
|
|
import Dhall.Import (Imported(..))
|
2016-11-05 16:36:16 +01:00
|
|
|
import Dhall.Parser (Src(..))
|
2016-11-21 01:25:55 +01:00
|
|
|
import Dhall.TypeCheck (DetailedTypeError(..), TypeError, X)
|
2016-09-09 18:17:25 +02:00
|
|
|
import GHC.Generics
|
|
|
|
import Numeric.Natural (Natural)
|
2016-09-19 00:38:36 +02:00
|
|
|
import Prelude hiding (maybe)
|
2016-11-03 17:40:29 +01:00
|
|
|
import Text.Trifecta.Delta (Delta(..))
|
2016-09-09 18:17:25 +02:00
|
|
|
|
|
|
|
import qualified Control.Exception
|
2016-11-05 16:36:16 +01:00
|
|
|
import qualified Data.ByteString.Lazy
|
2016-09-09 18:17:25 +02:00
|
|
|
import qualified Data.Map
|
2017-02-05 19:31:03 +01:00
|
|
|
import qualified Data.Text
|
2016-09-09 18:17:25 +02:00
|
|
|
import qualified Data.Text.Lazy
|
2016-10-11 18:18:52 +02:00
|
|
|
import qualified Data.Text.Lazy.Builder
|
2016-11-05 16:36:16 +01:00
|
|
|
import qualified Data.Text.Lazy.Encoding
|
2016-09-19 00:38:36 +02:00
|
|
|
import qualified Data.Vector
|
2016-09-09 18:17:25 +02:00
|
|
|
import qualified Dhall.Core
|
|
|
|
import qualified Dhall.Import
|
2016-10-31 03:31:47 +01:00
|
|
|
import qualified Dhall.Parser
|
2016-10-18 03:34:51 +02:00
|
|
|
import qualified Dhall.TypeCheck
|
2017-02-05 19:31:03 +01:00
|
|
|
import qualified NeatInterpolation
|
2016-09-09 18:17:25 +02:00
|
|
|
|
|
|
|
throws :: Exception e => Either e a -> IO a
|
|
|
|
throws (Left e) = Control.Exception.throwIO e
|
|
|
|
throws (Right r) = return r
|
|
|
|
|
2017-02-05 19:31:03 +01:00
|
|
|
{-| Every `Type` must obey the contract that if an expression's type matches the
|
|
|
|
the `expected` type then the `extract` function must succeed. If not, then
|
|
|
|
this exception is thrown
|
|
|
|
|
|
|
|
This exception indicates that an invalid `Type` was provided to the `input`
|
|
|
|
function
|
|
|
|
-}
|
|
|
|
data InvalidType = InvalidType deriving (Typeable)
|
|
|
|
|
|
|
|
_ERROR :: Data.Text.Text
|
|
|
|
_ERROR = "\ESC[1;31mError\ESC[0m"
|
|
|
|
|
|
|
|
instance Show InvalidType where
|
|
|
|
show InvalidType = Data.Text.unpack [NeatInterpolation.text|
|
|
|
|
$_ERROR: Invalid Dhall.Type
|
|
|
|
|
|
|
|
Every Type must provide an extract function that succeeds if an expression
|
|
|
|
matches the expected type. You provided a Type that disobeys this contract
|
|
|
|
|]
|
|
|
|
|
|
|
|
instance Exception InvalidType
|
|
|
|
|
2016-09-09 18:17:25 +02:00
|
|
|
{-| Type-check and evaluate a Dhall program, decoding the result into Haskell
|
|
|
|
|
|
|
|
The first argument determines the type of value that you decode:
|
|
|
|
|
2016-09-10 04:02:13 +02:00
|
|
|
>>> input integer "2"
|
|
|
|
2
|
2017-02-05 16:23:25 +01:00
|
|
|
>>> input (vector double) "[1.0, 2.0]"
|
2016-09-10 04:02:13 +02:00
|
|
|
[1.0,2.0]
|
2016-09-09 18:17:25 +02:00
|
|
|
|
|
|
|
Use `auto` to automatically select which type to decode based on the
|
|
|
|
inferred return type:
|
|
|
|
|
2016-09-10 04:02:13 +02:00
|
|
|
>>> input auto "True" :: IO Bool
|
|
|
|
True
|
2016-09-09 18:17:25 +02:00
|
|
|
-}
|
|
|
|
input
|
|
|
|
:: Type a
|
|
|
|
-- ^ The type of value to decode from Dhall to Haskell
|
2016-10-31 02:33:14 +01:00
|
|
|
-> Text
|
2016-09-09 18:17:25 +02:00
|
|
|
-- ^ The Dhall program
|
|
|
|
-> IO a
|
|
|
|
-- ^ The decoded value in Haskell
|
2017-01-29 23:10:28 +01:00
|
|
|
input (Type {..}) txt = do
|
2016-11-03 17:40:29 +01:00
|
|
|
let delta = Directed "(input)" 0 0 0 0
|
2017-02-05 19:31:03 +01:00
|
|
|
expr <- throws (Dhall.Parser.exprFromText delta txt)
|
|
|
|
expr' <- Dhall.Import.load expr
|
2016-11-05 16:36:16 +01:00
|
|
|
let suffix =
|
|
|
|
( Data.ByteString.Lazy.toStrict
|
|
|
|
. Data.Text.Lazy.Encoding.encodeUtf8
|
|
|
|
. Data.Text.Lazy.Builder.toLazyText
|
2016-12-05 00:19:01 +01:00
|
|
|
. build
|
2016-11-05 16:36:16 +01:00
|
|
|
) expected
|
|
|
|
let annot = case expr' of
|
|
|
|
Note (Src begin end bytes) _ ->
|
|
|
|
Note (Src begin end bytes') (Annot expr' expected)
|
|
|
|
where
|
|
|
|
bytes' = bytes <> " : " <> suffix
|
|
|
|
_ ->
|
|
|
|
Annot expr' expected
|
2017-01-29 23:10:28 +01:00
|
|
|
_ <- throws (Dhall.TypeCheck.typeOf annot)
|
2016-09-09 18:17:25 +02:00
|
|
|
case extract (Dhall.Core.normalize expr') of
|
|
|
|
Just x -> return x
|
2017-02-05 19:31:03 +01:00
|
|
|
Nothing -> Control.Exception.throwIO InvalidType
|
2016-09-09 18:17:25 +02:00
|
|
|
|
2016-11-21 01:25:55 +01:00
|
|
|
{-| 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
|
|
|
|
|
|
|
|
-}
|
|
|
|
detailed :: IO a -> IO a
|
|
|
|
detailed =
|
|
|
|
Control.Exception.handle handler1 . Control.Exception.handle handler0
|
|
|
|
where
|
|
|
|
handler0 :: Imported (TypeError Src) -> IO a
|
|
|
|
handler0 (Imported ps e) =
|
|
|
|
Control.Exception.throwIO (Imported ps (DetailedTypeError e))
|
|
|
|
|
|
|
|
handler1 :: TypeError Src -> IO a
|
|
|
|
handler1 e = Control.Exception.throwIO (DetailedTypeError e)
|
|
|
|
|
2016-09-10 04:02:13 +02:00
|
|
|
{-| A @(Type a)@ represents a way to marshal a value of type @\'a\'@ from Dhall
|
2016-09-09 18:17:25 +02:00
|
|
|
into Haskell
|
|
|
|
|
|
|
|
You can produce `Type`s either explicitly:
|
|
|
|
|
2016-09-15 18:03:12 +02:00
|
|
|
> example :: Type (Vector Text)
|
|
|
|
> example = vector text
|
2016-09-09 18:17:25 +02:00
|
|
|
|
|
|
|
... or implicitly using `auto`:
|
|
|
|
|
2016-09-15 18:03:12 +02:00
|
|
|
> example :: Type (Vector Text)
|
2016-09-09 18:17:25 +02:00
|
|
|
> example = auto
|
|
|
|
|
|
|
|
You can consume `Type`s using the `input` function:
|
|
|
|
|
|
|
|
> input :: Type a -> Text -> IO a
|
|
|
|
-}
|
|
|
|
data Type a = Type
|
2016-10-30 05:48:18 +01:00
|
|
|
{ extract :: Expr X X -> Maybe a
|
|
|
|
, expected :: Expr Src X
|
2016-09-09 18:17:25 +02:00
|
|
|
}
|
|
|
|
deriving (Functor)
|
|
|
|
|
|
|
|
{-| Decode a `Bool`
|
|
|
|
|
|
|
|
>>> input bool "True"
|
|
|
|
True
|
|
|
|
-}
|
|
|
|
bool :: Type Bool
|
|
|
|
bool = Type {..}
|
|
|
|
where
|
|
|
|
extract (BoolLit b) = pure b
|
|
|
|
extract _ = Nothing
|
|
|
|
|
|
|
|
expected = Bool
|
|
|
|
|
|
|
|
{-| Decode a `Natural`
|
|
|
|
|
|
|
|
>>> input natural "+42"
|
|
|
|
42
|
|
|
|
-}
|
|
|
|
natural :: Type Natural
|
|
|
|
natural = Type {..}
|
|
|
|
where
|
|
|
|
extract (NaturalLit n) = pure n
|
|
|
|
extract _ = empty
|
|
|
|
|
|
|
|
expected = Natural
|
|
|
|
|
|
|
|
{-| Decode an `Integer`
|
|
|
|
|
|
|
|
>>> input integer "42"
|
|
|
|
42
|
|
|
|
-}
|
|
|
|
integer :: Type Integer
|
|
|
|
integer = Type {..}
|
|
|
|
where
|
|
|
|
extract (IntegerLit n) = pure n
|
|
|
|
extract _ = empty
|
|
|
|
|
|
|
|
expected = Integer
|
|
|
|
|
|
|
|
{-| Decode a `Double`
|
|
|
|
|
|
|
|
>>> input double "42.0"
|
|
|
|
42.0
|
|
|
|
-}
|
|
|
|
double :: Type Double
|
|
|
|
double = Type {..}
|
|
|
|
where
|
|
|
|
extract (DoubleLit n) = pure n
|
|
|
|
extract _ = empty
|
|
|
|
|
|
|
|
expected = Double
|
|
|
|
|
|
|
|
{-| Decode `Text`
|
|
|
|
|
|
|
|
>>> input text "\"Test\""
|
|
|
|
"Test"
|
|
|
|
-}
|
|
|
|
text :: Type Text
|
|
|
|
text = Type {..}
|
|
|
|
where
|
2016-10-11 18:18:52 +02:00
|
|
|
extract (TextLit t) = pure (Data.Text.Lazy.Builder.toLazyText t)
|
2016-09-09 18:17:25 +02:00
|
|
|
extract _ = empty
|
|
|
|
|
|
|
|
expected = Text
|
|
|
|
|
2016-09-19 00:38:36 +02:00
|
|
|
{-| Decode a `Maybe`
|
|
|
|
|
2016-12-05 00:10:08 +01:00
|
|
|
>>> input (maybe integer) "[1] : Optional Integer"
|
|
|
|
Just 1
|
2016-09-19 00:38:36 +02:00
|
|
|
-}
|
|
|
|
maybe :: Type a -> Type (Maybe a)
|
|
|
|
maybe (Type extractIn expectedIn) = Type extractOut expectedOut
|
|
|
|
where
|
2016-11-12 17:31:13 +01:00
|
|
|
extractOut (OptionalLit _ es) = traverse extractIn es'
|
2016-09-19 00:38:36 +02:00
|
|
|
where
|
|
|
|
es' = if Data.Vector.null es then Nothing else Just (Data.Vector.head es)
|
2017-01-29 23:10:28 +01:00
|
|
|
extractOut _ = Nothing
|
2016-09-19 00:38:36 +02:00
|
|
|
|
2016-11-12 17:31:13 +01:00
|
|
|
expectedOut = App Optional expectedIn
|
2016-09-19 00:38:36 +02:00
|
|
|
|
2016-09-09 18:17:25 +02:00
|
|
|
{-| Decode a `Vector`
|
|
|
|
|
2017-02-05 16:23:25 +01:00
|
|
|
>>> input (vector integer) "[1, 2, 3]"
|
2016-09-09 18:17:25 +02:00
|
|
|
[1,2,3]
|
|
|
|
-}
|
|
|
|
vector :: Type a -> Type (Vector a)
|
|
|
|
vector (Type extractIn expectedIn) = Type extractOut expectedOut
|
|
|
|
where
|
|
|
|
extractOut (ListLit _ es) = traverse extractIn es
|
2017-01-29 23:10:28 +01:00
|
|
|
extractOut _ = Nothing
|
2016-09-09 18:17:25 +02:00
|
|
|
|
2016-09-15 18:03:12 +02:00
|
|
|
expectedOut = App List expectedIn
|
2016-09-09 18:17:25 +02:00
|
|
|
|
|
|
|
{-| Any value that implements `Interpret` can be automatically decoded based on
|
|
|
|
the inferred return type of `input`
|
|
|
|
|
2017-02-05 16:23:25 +01:00
|
|
|
>>> input auto "[1, 2, 3]" :: IO (Vector Integer)
|
2016-09-09 18:17:25 +02:00
|
|
|
[1,2,3]
|
2016-09-10 04:02:13 +02:00
|
|
|
|
|
|
|
This class auto-generates a default implementation for records that
|
2017-02-05 16:27:07 +01:00
|
|
|
implement `Generic`. This does not auto-generate an instance for recursive
|
|
|
|
types.
|
2016-09-09 18:17:25 +02:00
|
|
|
-}
|
|
|
|
class Interpret a where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
autoWith:: InterpretOptions -> Type a
|
|
|
|
default autoWith
|
|
|
|
:: (Generic a, GenericInterpret (Rep a)) => InterpretOptions -> Type a
|
|
|
|
autoWith options = fmap GHC.Generics.to (genericAutoWith options)
|
2016-09-09 18:17:25 +02:00
|
|
|
|
|
|
|
instance Interpret Bool where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
autoWith _ = bool
|
2016-09-09 18:17:25 +02:00
|
|
|
|
|
|
|
instance Interpret Natural where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
autoWith _ = natural
|
2016-09-09 18:17:25 +02:00
|
|
|
|
|
|
|
instance Interpret Integer where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
autoWith _ = integer
|
2016-09-09 18:17:25 +02:00
|
|
|
|
|
|
|
instance Interpret Double where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
autoWith _ = double
|
2016-09-09 18:17:25 +02:00
|
|
|
|
|
|
|
instance Interpret Text where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
autoWith _ = text
|
2016-09-09 18:17:25 +02:00
|
|
|
|
2016-09-19 00:38:36 +02:00
|
|
|
instance Interpret a => Interpret (Maybe a) where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
autoWith _ = maybe auto
|
2016-09-19 00:38:36 +02:00
|
|
|
|
2016-09-09 18:17:25 +02:00
|
|
|
instance Interpret a => Interpret (Vector a) where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
autoWith _ = vector auto
|
2016-09-09 18:17:25 +02:00
|
|
|
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
{-| Use the default options for interpreting a configuration file
|
2017-02-23 18:35:52 +01:00
|
|
|
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
> auto = autoWith defaultInterpretOptions
|
2017-02-23 18:35:52 +01:00
|
|
|
-}
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
auto :: Interpret a => Type a
|
|
|
|
auto = autoWith defaultInterpretOptions
|
2017-02-23 18:35:52 +01:00
|
|
|
|
|
|
|
{-| Use these options to tweak how Dhall derives a generic implementation of
|
|
|
|
`Interpret`
|
|
|
|
-}
|
|
|
|
data InterpretOptions = InterpretOptions
|
|
|
|
{ fieldModifier :: Text -> Text
|
|
|
|
-- ^ Function used to transform Haskell field names into their corresponding
|
|
|
|
-- Dhall field names
|
|
|
|
, constructorModifier :: Text -> Text
|
|
|
|
-- ^ Function used to transform Haskell constructor names into their
|
|
|
|
-- corresponding Dhall alternative names
|
|
|
|
}
|
|
|
|
|
|
|
|
{-| Default interpret options, which you can tweak or override, like this:
|
|
|
|
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
> autoWith
|
|
|
|
> (defaultInterpretOptions { fieldModifier = Data.Text.Lazy.dropWhile (== '_') })
|
2017-02-23 18:35:52 +01:00
|
|
|
-}
|
|
|
|
defaultInterpretOptions :: InterpretOptions
|
|
|
|
defaultInterpretOptions = InterpretOptions
|
|
|
|
{ fieldModifier = id
|
|
|
|
, constructorModifier = id
|
|
|
|
}
|
|
|
|
|
|
|
|
{-| This is the underlying class that powers the `Interpret` class's support
|
|
|
|
for automatically deriving a generic implementation
|
|
|
|
-}
|
2016-09-09 18:17:25 +02:00
|
|
|
class GenericInterpret f where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
genericAutoWith :: InterpretOptions -> Type (f a)
|
2016-09-09 18:17:25 +02:00
|
|
|
|
2016-10-16 02:35:51 +02:00
|
|
|
instance GenericInterpret f => GenericInterpret (M1 D d f) where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
genericAutoWith = fmap (fmap M1) genericAutoWith
|
2016-10-16 02:35:51 +02:00
|
|
|
|
|
|
|
instance GenericInterpret V1 where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
genericAutoWith _ = Type {..}
|
2016-10-16 02:35:51 +02:00
|
|
|
where
|
|
|
|
extract _ = Nothing
|
|
|
|
|
|
|
|
expected = Union Data.Map.empty
|
|
|
|
|
2016-12-05 16:33:09 +01:00
|
|
|
instance (Constructor c1, Constructor c2, GenericInterpret f1, GenericInterpret f2) => GenericInterpret (M1 C c1 f1 :+: M1 C c2 f2) where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
genericAutoWith options@(InterpretOptions {..}) = Type {..}
|
2016-10-16 02:35:51 +02:00
|
|
|
where
|
2016-12-05 16:33:09 +01:00
|
|
|
nL :: M1 i c1 f1 a
|
|
|
|
nL = undefined
|
2016-10-16 02:35:51 +02:00
|
|
|
|
2016-12-05 16:33:09 +01:00
|
|
|
nR :: M1 i c2 f2 a
|
|
|
|
nR = undefined
|
|
|
|
|
2017-02-23 18:35:52 +01:00
|
|
|
nameL = constructorModifier (Data.Text.Lazy.pack (conName nL))
|
|
|
|
nameR = constructorModifier (Data.Text.Lazy.pack (conName nR))
|
2016-12-05 16:33:09 +01:00
|
|
|
|
|
|
|
extract (UnionLit name e _)
|
|
|
|
| name == nameL = fmap (L1 . M1) (extractL e)
|
|
|
|
| name == nameR = fmap (R1 . M1) (extractR e)
|
|
|
|
| otherwise = Nothing
|
2017-01-29 23:10:28 +01:00
|
|
|
extract _ = Nothing
|
2016-12-05 16:33:09 +01:00
|
|
|
|
|
|
|
expected =
|
|
|
|
Union (Data.Map.fromList [(nameL, expectedL), (nameR, expectedR)])
|
|
|
|
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
Type extractL expectedL = genericAutoWith options
|
|
|
|
Type extractR expectedR = genericAutoWith options
|
2016-12-05 16:33:09 +01:00
|
|
|
|
|
|
|
instance (Constructor c, GenericInterpret (f :+: g), GenericInterpret h) => GenericInterpret ((f :+: g) :+: M1 C c h) where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
genericAutoWith options@(InterpretOptions {..}) = Type {..}
|
2016-12-05 16:33:09 +01:00
|
|
|
where
|
|
|
|
n :: M1 i c h a
|
|
|
|
n = undefined
|
|
|
|
|
2017-02-23 18:35:52 +01:00
|
|
|
name = constructorModifier (Data.Text.Lazy.pack (conName n))
|
2016-12-05 16:33:09 +01:00
|
|
|
|
|
|
|
extract u@(UnionLit name' e _)
|
|
|
|
| name == name' = fmap (R1 . M1) (extractR e)
|
|
|
|
| otherwise = fmap L1 (extractL u)
|
2017-01-29 23:10:28 +01:00
|
|
|
extract _ = Nothing
|
2016-12-05 16:33:09 +01:00
|
|
|
|
|
|
|
expected = Union (Data.Map.insert name expectedR expectedL)
|
2016-10-16 02:35:51 +02:00
|
|
|
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
Type extractL (Union expectedL) = genericAutoWith options
|
|
|
|
Type extractR expectedR = genericAutoWith options
|
2016-10-16 02:35:51 +02:00
|
|
|
|
2016-12-05 16:33:09 +01:00
|
|
|
instance (Constructor c, GenericInterpret f, GenericInterpret (g :+: h)) => GenericInterpret (M1 C c f :+: (g :+: h)) where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
genericAutoWith options@(InterpretOptions {..}) = Type {..}
|
2016-10-16 02:35:51 +02:00
|
|
|
where
|
|
|
|
n :: M1 i c f a
|
|
|
|
n = undefined
|
|
|
|
|
2017-02-23 18:35:52 +01:00
|
|
|
name = constructorModifier (Data.Text.Lazy.pack (conName n))
|
2016-10-16 02:35:51 +02:00
|
|
|
|
2016-12-05 16:33:09 +01:00
|
|
|
extract u@(UnionLit name' e _)
|
|
|
|
| name == name' = fmap (L1 . M1) (extractL e)
|
|
|
|
| otherwise = fmap R1 (extractR u)
|
2017-01-29 23:10:28 +01:00
|
|
|
extract _ = Nothing
|
2016-12-05 16:33:09 +01:00
|
|
|
|
|
|
|
expected = Union (Data.Map.insert name expectedL expectedR)
|
|
|
|
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
Type extractL expectedL = genericAutoWith options
|
|
|
|
Type extractR (Union expectedR) = genericAutoWith options
|
2016-12-05 16:33:09 +01:00
|
|
|
|
|
|
|
instance (GenericInterpret (f :+: g), GenericInterpret (h :+: i)) => GenericInterpret ((f :+: g) :+: (h :+: i)) where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
genericAutoWith options = Type {..}
|
2016-12-05 16:33:09 +01:00
|
|
|
where
|
|
|
|
extract e = fmap L1 (extractL e) <|> fmap R1 (extractR e)
|
2016-10-16 02:35:51 +02:00
|
|
|
|
2016-12-05 16:33:09 +01:00
|
|
|
expected = Union (Data.Map.union expectedL expectedR)
|
2016-10-16 02:35:51 +02:00
|
|
|
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
Type extractL (Union expectedL) = genericAutoWith options
|
|
|
|
Type extractR (Union expectedR) = genericAutoWith options
|
2016-12-05 16:33:09 +01:00
|
|
|
|
|
|
|
instance GenericInterpret f => GenericInterpret (M1 C c f) where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
genericAutoWith = fmap (fmap M1) genericAutoWith
|
2016-10-16 02:35:51 +02:00
|
|
|
|
2016-09-09 18:17:25 +02:00
|
|
|
instance GenericInterpret U1 where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
genericAutoWith _ = Type {..}
|
2016-09-09 18:17:25 +02:00
|
|
|
where
|
|
|
|
extract _ = Just U1
|
|
|
|
|
|
|
|
expected = Record (Data.Map.fromList [])
|
|
|
|
|
|
|
|
instance (GenericInterpret f, GenericInterpret g) => GenericInterpret (f :*: g) where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
genericAutoWith options = Type {..}
|
2016-09-09 18:17:25 +02:00
|
|
|
where
|
|
|
|
extract = liftA2 (liftA2 (:*:)) extractL extractR
|
|
|
|
|
|
|
|
expected = Record (Data.Map.union ktsL ktsR)
|
|
|
|
where
|
|
|
|
Record ktsL = expectedL
|
|
|
|
Record ktsR = expectedR
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
Type extractL expectedL = genericAutoWith options
|
|
|
|
Type extractR expectedR = genericAutoWith options
|
2016-09-09 18:17:25 +02:00
|
|
|
|
|
|
|
instance (Selector s, Interpret a) => GenericInterpret (M1 S s (K1 i a)) where
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
genericAutoWith opts@(InterpretOptions {..}) = Type {..}
|
2016-09-09 18:17:25 +02:00
|
|
|
where
|
|
|
|
n :: M1 i s f a
|
|
|
|
n = undefined
|
|
|
|
|
|
|
|
extract (RecordLit m) = do
|
|
|
|
case selName n of
|
|
|
|
"" -> Nothing
|
|
|
|
name -> do
|
2017-02-23 18:35:52 +01:00
|
|
|
let name' = fieldModifier (Data.Text.Lazy.pack name)
|
|
|
|
e <- Data.Map.lookup name' m
|
2016-09-09 18:17:25 +02:00
|
|
|
fmap (M1 . K1) (extract' e)
|
|
|
|
extract _ = Nothing
|
|
|
|
|
|
|
|
expected = Record (Data.Map.fromList [(key, expected')])
|
|
|
|
where
|
2017-02-23 18:35:52 +01:00
|
|
|
key = fieldModifier (Data.Text.Lazy.pack (selName n))
|
2016-09-09 18:17:25 +02:00
|
|
|
|
Fix `InterpretOptions` to affect nested records. Fixes #33
Consider the following program which marshals a Dhall record into Haskell:
```haskell
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
import Dhall hiding (auto)
import qualified Data.Text.Lazy
interpretOptions :: InterpretOptions
interpretOptions = defaultInterpretOptions
{ fieldModifier = Data.Text.Lazy.dropWhile (== '_') }
data GitRepo = GitRepo
{ _host :: Text
, _repo :: Text
} deriving (Generic, Interpret, Show)
data BoxConfig = BoxConfig
{ _userName :: Text
, _dotfilesRepo :: GitRepo
} deriving (Generic, Interpret, Show)
main :: IO ()
main = do
x <- Dhall.input (autoWith interpretOptions) "./config"
print (x :: BoxConfig)
```
The above program is a common pattern when mixing Dhall records with lenses
(which typically prefix the original fields with "_").
Before this change, the above program expects a record of the following type:
```
{ userName : Text, dotfilesRepo : { _host : Text, _repo : Text } }
```
Note that the sub-record ignores the `InterpretOptions` and incorrectly includes
the underscore in the expected field names.
This change fixes the derived `Interpret` instance for records to correctly
thread `InterpretOptions` to nested records.
This required a change to the `auto` method of the `Interpret` class to
accept `InterpretOptions`, otherwise there is no way to supply the
`InterpretOptions` record to sub-records. This modified `auto` method is now
called `autoWith`. I still include an `auto` function that uses
`defaultInterpretOptions` consistent with the old behavior.
2017-03-26 18:20:04 +02:00
|
|
|
Type extract' expected' = autoWith opts
|