1
+ {-# LANGUAGE BangPatterns #-}
1
2
{-# LANGUAGE CPP #-}
2
3
{-# LANGUAGE DeriveTraversable #-}
3
4
{-# LANGUAGE FlexibleContexts #-}
@@ -20,7 +21,7 @@ module Dhall.TH
20
21
, defaultGenerateOptions
21
22
) where
22
23
23
- import Data.Bifunctor ( first )
24
+ import Data.Map ( Map )
24
25
import Data.Text (Text )
25
26
import Dhall (FromDhall , ToDhall )
26
27
import Dhall.Syntax (Expr (.. ), FunctionBinding (.. ), Var (.. ))
@@ -165,6 +166,22 @@ toNestedHaskellType typeParams haskellTypes = loop
165
166
message dhallType = Pretty. renderString (Dhall.Pretty. layout (document dhallType))
166
167
167
168
loop dhallType = case dhallType of
169
+ Var v
170
+ | Just (V param index) <- List. find (v == ) typeParams -> do
171
+ let name = Syntax. mkName $ (Text. unpack param) ++ (show index)
172
+
173
+ return (VarT name)
174
+
175
+ | otherwise -> fail $ message v
176
+
177
+ _ | Just haskellType <- List. find (predicate dhallType) haskellTypes ->
178
+ case haskellType of
179
+ Predefined {.. } -> return haskellSplice
180
+ _ -> do
181
+ let name = Syntax. mkName (Text. unpack (typeName haskellType))
182
+
183
+ return (ConT name)
184
+
168
185
Bool ->
169
186
return (ConT ''Bool)
170
187
@@ -205,19 +222,7 @@ toNestedHaskellType typeParams haskellTypes = loop
205
222
206
223
return (AppT haskellAppType haskellElementType)
207
224
208
- Var v
209
- | Just (V param index) <- List. find (v == ) typeParams -> do
210
- let name = Syntax. mkName $ (Text. unpack param) ++ (show index)
211
-
212
- return (VarT name)
213
-
214
- | otherwise -> fail $ message v
215
-
216
- _ | Just haskellType <- List. find (predicate dhallType) haskellTypes -> do
217
- let name = Syntax. mkName (Text. unpack (typeName haskellType))
218
-
219
- return (ConT name)
220
- | otherwise -> fail $ message dhallType
225
+ _ -> fail $ message dhallType
221
226
222
227
-- | A deriving clause for `Generic`.
223
228
derivingGenericClause :: DerivClause
@@ -256,12 +261,8 @@ toDeclaration globalGenerateOptions haskellTypes typ =
256
261
SingleConstructorWith {.. } -> uncurry (fromSingle options typeName constructorName) $ getTypeParams code
257
262
MultipleConstructors {.. } -> uncurry (fromMulti globalGenerateOptions typeName) $ getTypeParams code
258
263
MultipleConstructorsWith {.. } -> uncurry (fromMulti options typeName) $ getTypeParams code
264
+ Predefined {} -> return []
259
265
where
260
- getTypeParams = first numberConsecutive . getTypeParams_ []
261
-
262
- getTypeParams_ acc (Lam _ (FunctionBinding _ v _ _ _) rest) = getTypeParams_ (v: acc) rest
263
- getTypeParams_ acc rest = (acc, rest)
264
-
265
266
#if MIN_VERSION_template_haskell(2,21,0)
266
267
toTypeVar (V n i) = Syntax. PlainTV (Syntax. mkName (Text. unpack n ++ show i)) Syntax. BndrInvis
267
268
#elif MIN_VERSION_template_haskell(2,17,0)
@@ -337,13 +338,21 @@ toDeclaration globalGenerateOptions haskellTypes typ =
337
338
, " ... which is not a union type."
338
339
]
339
340
340
- -- | Number each variable, starting at 0
341
- numberConsecutive :: [Text. Text ] -> [Var ]
342
- numberConsecutive = snd . List. mapAccumR go Map. empty . reverse
341
+ getTypeParams :: Expr s a -> ([Var ], Expr s a )
342
+ getTypeParams = go []
343
343
where
344
- go m k =
345
- let (i, m') = Map. updateLookupWithKey (\ _ j -> Just $ j + 1 ) k m
346
- in maybe ((Map. insert k 0 m'), (V k 0 )) (\ i' -> (m', (V k i'))) i
344
+ go :: [Text ] -> Expr s a -> ([Var ], Expr s a )
345
+ go ! acc (Lam _ (FunctionBinding _ v _ _ _) rest) = go (v: acc) rest
346
+ go ! acc rest = (numberConsecutive $ reverse acc, rest)
347
+
348
+ -- | Number each variable, starting at 0
349
+ numberConsecutive :: [Text. Text ] -> [Var ]
350
+ numberConsecutive = snd . List. mapAccumR numberVar Map. empty
351
+
352
+ numberVar :: Map Text Int -> Text -> (Map Text Int , Var )
353
+ numberVar m k =
354
+ let (i, m') = Map. updateLookupWithKey (\ _ j -> Just $ j + 1 ) k m
355
+ in maybe ((Map. insert k 0 m'), (V k 0 )) (\ i' -> (m', (V k i'))) i
347
356
348
357
-- | Convert a Dhall type to the corresponding Haskell constructor
349
358
toConstructor
@@ -439,8 +448,8 @@ data HaskellType code
439
448
, code :: code
440
449
-- ^ Dhall code that evaluates to a type
441
450
}
442
- -- | Generate a Haskell type with more than one constructor from a Dhall
443
- -- union type.
451
+ -- | Like 'MultipleConstructors', but also takes some 'GenerateOptions' to
452
+ -- use for the generation of the Haskell type.
444
453
| MultipleConstructorsWith
445
454
{ options :: GenerateOptions
446
455
-- ^ The 'GenerateOptions' to use then generating the Haskell type.
@@ -449,10 +458,8 @@ data HaskellType code
449
458
, code :: code
450
459
-- ^ Dhall code that evaluates to a union type
451
460
}
452
- -- | Generate a Haskell type with one constructor from any Dhall type.
453
- --
454
- -- To generate a constructor with multiple named fields, supply a Dhall
455
- -- record type. This does not support more than one anonymous field.
461
+ -- | Like 'SingleConstructor', but also takes some 'GenerateOptions' to use
462
+ -- for the generation of the Haskell type.
456
463
| SingleConstructorWith
457
464
{ options :: GenerateOptions
458
465
-- ^ The 'GenerateOptions' to use then generating the Haskell type.
@@ -463,6 +470,14 @@ data HaskellType code
463
470
, code :: code
464
471
-- ^ Dhall code that evaluates to a type
465
472
}
473
+ -- | Declare a predefined mapping from a Dhall type to an existing Haskell
474
+ -- type.
475
+ | Predefined
476
+ { haskellSplice :: Type
477
+ -- ^ An existing Haskell type
478
+ , code :: code
479
+ -- ^ Dhall code that evaluates to a type
480
+ }
466
481
deriving (Functor , Foldable , Traversable )
467
482
468
483
-- | This data type holds various options that let you control several aspects
0 commit comments