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 #-} @