Skip to content

Commit 009c1cf

Browse files
committed
Added SingleConstructorWith and MultipleConstructorsWith to Dhall.TH
1 parent 2b3a6bc commit 009c1cf

File tree

1 file changed

+47
-21
lines changed

1 file changed

+47
-21
lines changed

dhall/src/Dhall/TH.hs

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ import qualified Numeric.Natural
6161
import qualified Prettyprinter.Render.String as Pretty
6262
import qualified System.IO
6363

64-
64+
6565
{-| This fully resolves, type checks, and normalizes the expression, so the
6666
resulting AST is self-contained.
6767
@@ -161,9 +161,9 @@ toNestedHaskellType typeParams haskellTypes = loop
161161
, " \n"
162162
, "... which did not fit any of the above criteria."
163163
]
164-
164+
165165
message dhallType = Pretty.renderString (Dhall.Pretty.layout (document dhallType))
166-
166+
167167
loop dhallType = case dhallType of
168168
Bool ->
169169
return (ConT ''Bool)
@@ -204,7 +204,7 @@ toNestedHaskellType typeParams haskellTypes = loop
204204
haskellElementType <- loop dhallElementType
205205

206206
return (AppT haskellAppType haskellElementType)
207-
207+
208208
Var v
209209
| Just (V param index) <- List.find (v ==) typeParams -> do
210210
let name = Syntax.mkName $ (Text.unpack param) ++ (show index)
@@ -250,20 +250,18 @@ toDeclaration
250250
-> [HaskellType (Expr s a)]
251251
-> HaskellType (Expr s a)
252252
-> Q [Dec]
253-
toDeclaration generateOptions@GenerateOptions{..} haskellTypes typ =
253+
toDeclaration globalGenerateOptions haskellTypes typ =
254254
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
257259
where
258260
getTypeParams = first numberConsecutive . getTypeParams_ []
259-
261+
260262
getTypeParams_ acc (Lam _ (FunctionBinding _ v _ _ _) rest) = getTypeParams_ (v:acc) rest
261263
getTypeParams_ acc rest = (acc, rest)
262264

263-
derivingClauses = [ derivingGenericClause | generateFromDhallInstance || generateToDhallInstance ]
264-
265-
interpretOptions = generateToInterpretOptions generateOptions typ
266-
267265
#if MIN_VERSION_template_haskell(2,21,0)
268266
toTypeVar (V n i) = Syntax.PlainTV (Syntax.mkName (Text.unpack n ++ show i)) Syntax.BndrInvis
269267
#elif MIN_VERSION_template_haskell(2,17,0)
@@ -272,28 +270,32 @@ toDeclaration generateOptions@GenerateOptions{..} haskellTypes typ =
272270
toTypeVar (V n i) = Syntax.PlainTV (Syntax.mkName (Text.unpack n ++ show i))
273271
#endif
274272

275-
toDataD typeName typeParams constructors = do
273+
toDataD generateOptions@GenerateOptions{..} typeName typeParams constructors = do
276274
let name = Syntax.mkName (Text.unpack typeName)
277275

278276
let params = fmap toTypeVar typeParams
279277

278+
let interpretOptions = generateToInterpretOptions generateOptions typ
279+
280+
let derivingClauses = [ derivingGenericClause | generateFromDhallInstance || generateToDhallInstance ]
281+
280282
fmap concat . sequence $
281283
[pure [DataD [] name params Nothing constructors derivingClauses]] <>
282284
[ fromDhallInstance name interpretOptions | generateFromDhallInstance ] <>
283285
[ toDhallInstance name interpretOptions | generateToDhallInstance ]
284286

285-
fromSingle typeName constructorName typeParams dhallType = do
287+
fromSingle generateOptions typeName constructorName typeParams dhallType = do
286288
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
291293
Union kts -> do
292294
constructors <- traverse (toConstructor typeParams generateOptions haskellTypes typeName) (Dhall.Map.toList kts)
293295

294-
toDataD typeName typeParams constructors
295-
296-
_ -> fail $ message dhallType
296+
toDataD generateOptions typeName typeParams constructors
297+
298+
_ -> fail $ message dhallType
297299

298300
message dhallType = Pretty.renderString (Dhall.Pretty.layout $ document dhallType)
299301

@@ -437,6 +439,30 @@ data HaskellType code
437439
, code :: code
438440
-- ^ Dhall code that evaluates to a type
439441
}
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+
}
440466
deriving (Functor, Foldable, Traversable)
441467

442468
-- | This data type holds various options that let you control several aspects

0 commit comments

Comments
 (0)