@@ -61,7 +61,7 @@ import qualified Numeric.Natural
61
61
import qualified Prettyprinter.Render.String as Pretty
62
62
import qualified System.IO
63
63
64
-
64
+
65
65
{-| This fully resolves, type checks, and normalizes the expression, so the
66
66
resulting AST is self-contained.
67
67
@@ -161,9 +161,9 @@ toNestedHaskellType typeParams haskellTypes = loop
161
161
, " \n "
162
162
, " ... which did not fit any of the above criteria."
163
163
]
164
-
164
+
165
165
message dhallType = Pretty. renderString (Dhall.Pretty. layout (document dhallType))
166
-
166
+
167
167
loop dhallType = case dhallType of
168
168
Bool ->
169
169
return (ConT ''Bool)
@@ -204,7 +204,7 @@ toNestedHaskellType typeParams haskellTypes = loop
204
204
haskellElementType <- loop dhallElementType
205
205
206
206
return (AppT haskellAppType haskellElementType)
207
-
207
+
208
208
Var v
209
209
| Just (V param index) <- List. find (v == ) typeParams -> do
210
210
let name = Syntax. mkName $ (Text. unpack param) ++ (show index)
@@ -250,20 +250,18 @@ toDeclaration
250
250
-> [HaskellType (Expr s a )]
251
251
-> HaskellType (Expr s a )
252
252
-> Q [Dec ]
253
- toDeclaration generateOptions @ GenerateOptions { .. } haskellTypes typ =
253
+ toDeclaration globalGenerateOptions haskellTypes typ =
254
254
case typ of
255
- SingleConstructor {.. } -> uncurry (fromSingle typeName constructorName) $ getTypeParams code
256
- MultipleConstructors {.. } -> uncurry (fromMulti typeName) $ getTypeParams code
255
+ SingleConstructor {.. } -> uncurry (fromSingle globalGenerateOptions typeName constructorName) $ getTypeParams code
256
+ SingleConstructorWith {.. } -> uncurry (fromSingle options typeName constructorName) $ getTypeParams code
257
+ MultipleConstructors {.. } -> uncurry (fromMulti globalGenerateOptions typeName) $ getTypeParams code
258
+ MultipleConstructorsWith {.. } -> uncurry (fromMulti options typeName) $ getTypeParams code
257
259
where
258
260
getTypeParams = first numberConsecutive . getTypeParams_ []
259
-
261
+
260
262
getTypeParams_ acc (Lam _ (FunctionBinding _ v _ _ _) rest) = getTypeParams_ (v: acc) rest
261
263
getTypeParams_ acc rest = (acc, rest)
262
264
263
- derivingClauses = [ derivingGenericClause | generateFromDhallInstance || generateToDhallInstance ]
264
-
265
- interpretOptions = generateToInterpretOptions generateOptions typ
266
-
267
265
#if MIN_VERSION_template_haskell(2,21,0)
268
266
toTypeVar (V n i) = Syntax. PlainTV (Syntax. mkName (Text. unpack n ++ show i)) Syntax. BndrInvis
269
267
#elif MIN_VERSION_template_haskell(2,17,0)
@@ -272,28 +270,32 @@ toDeclaration generateOptions@GenerateOptions{..} haskellTypes typ =
272
270
toTypeVar (V n i) = Syntax. PlainTV (Syntax. mkName (Text. unpack n ++ show i))
273
271
#endif
274
272
275
- toDataD typeName typeParams constructors = do
273
+ toDataD generateOptions @ GenerateOptions { .. } typeName typeParams constructors = do
276
274
let name = Syntax. mkName (Text. unpack typeName)
277
275
278
276
let params = fmap toTypeVar typeParams
279
277
278
+ let interpretOptions = generateToInterpretOptions generateOptions typ
279
+
280
+ let derivingClauses = [ derivingGenericClause | generateFromDhallInstance || generateToDhallInstance ]
281
+
280
282
fmap concat . sequence $
281
283
[pure [DataD [] name params Nothing constructors derivingClauses]] <>
282
284
[ fromDhallInstance name interpretOptions | generateFromDhallInstance ] <>
283
285
[ toDhallInstance name interpretOptions | generateToDhallInstance ]
284
286
285
- fromSingle typeName constructorName typeParams dhallType = do
287
+ fromSingle generateOptions typeName constructorName typeParams dhallType = do
286
288
constructor <- toConstructor typeParams generateOptions haskellTypes typeName (constructorName, Just dhallType)
287
-
288
- toDataD typeName typeParams [constructor]
289
-
290
- fromMulti typeName typeParams dhallType = case dhallType of
289
+
290
+ toDataD generateOptions typeName typeParams [constructor]
291
+
292
+ fromMulti generateOptions typeName typeParams dhallType = case dhallType of
291
293
Union kts -> do
292
294
constructors <- traverse (toConstructor typeParams generateOptions haskellTypes typeName) (Dhall.Map. toList kts)
293
295
294
- toDataD typeName typeParams constructors
295
-
296
- _ -> fail $ message dhallType
296
+ toDataD generateOptions typeName typeParams constructors
297
+
298
+ _ -> fail $ message dhallType
297
299
298
300
message dhallType = Pretty. renderString (Dhall.Pretty. layout $ document dhallType)
299
301
@@ -437,6 +439,30 @@ data HaskellType code
437
439
, code :: code
438
440
-- ^ Dhall code that evaluates to a type
439
441
}
442
+ -- | Generate a Haskell type with more than one constructor from a Dhall
443
+ -- union type.
444
+ | MultipleConstructorsWith
445
+ { options :: GenerateOptions
446
+ -- ^ The 'GenerateOptions' to use then generating the Haskell type.
447
+ , typeName :: Text
448
+ -- ^ Name of the generated Haskell type
449
+ , code :: code
450
+ -- ^ Dhall code that evaluates to a union type
451
+ }
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.
456
+ | SingleConstructorWith
457
+ { options :: GenerateOptions
458
+ -- ^ The 'GenerateOptions' to use then generating the Haskell type.
459
+ , typeName :: Text
460
+ -- ^ Name of the generated Haskell type
461
+ , constructorName :: Text
462
+ -- ^ Name of the constructor
463
+ , code :: code
464
+ -- ^ Dhall code that evaluates to a type
465
+ }
440
466
deriving (Functor , Foldable , Traversable )
441
467
442
468
-- | This data type holds various options that let you control several aspects
0 commit comments