Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Documentation
asData ∷ Q [Dec] → Q [Dec] Source #
asData
takes a datatype declaration and "backs it" by BuiltinData
. It does
this by replacing the datatype with a newtype around BuiltinData
, and providing
pattern synonyms that match the behaviour of the original datatype.
Since BuiltinData
can only contain BuiltinData
, the pattern synonyms
encode and decode all the fields using toBuiltinData
and unsafeFromBuiltinData
.
That means that these operations are called on every pattern match or construction.
This *can* be very efficient if, for example, the datatypes for the fields have
also been defined with asData
, and so have trivial conversions to/from BuiltinData
(or have very cheap conversions, like Integer
and ByteString
).
But it can be very expensive otherwise, so take care.
Deriving clauses are transferred from the quoted declaration to the generated newtype
declaration. Note that you may therefore need to do strange things like use
deriving newtype
on a data declaration.
Example:
$(asData [d|
data Example a = Ex1 Integer | Ex2 a a
deriving newtype (Eq)
|])
becomes
@
newtype Example a = Example BuiltinData
deriving newtype (Eq)
pattern Ex1 :: (ToData a, UnsafeFromData a) => Integer -> Example a pattern Ex1 i Example (unsafeDataAsConstr - ((==) 0 -> True, [unsafeFromBuiltinData -> i])) where Ex1 i = Example (mkConstr 0 [toBuiltinData i])
pattern Ex2 :: (ToData a, UnsafeFromData a) => a -> a -> Example a pattern Ex2 a1 a2 Example (unsafeDataAsConstr - ((==) 1 -> True, [ unsafeFromBuiltinData -> a1 , unsafeFromBuiltinData -> a2 ])) where Ex2 a1 a2 = Example (mkConstr 1 [toBuiltinData a1, toBuiltinData a2])
{-# COMPLETE Ex1, Ex2 #-} @