| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Data.Record.Internal.Record.Resolution
Documentation
Arguments
| :: Quasi m | |
| => String | User-defined constructor |
| -> Name 'DataName 'Global | Internal constructor |
| -> m (Either String (Record ())) |
Resolve record info
When the quasi-quoter needs to turn
[lr| MkRecord { field2 = 5, field1 = True } |]into
_construct_MkRecord True 5
it needs to know the record definition: the types of all fields, and the order of all fields.
The primary means through which we achieve this is by looking up the
MetadataOf type family instance for the record, and then parsing that
(parseRecordInfo).
Unfortunately, however, this does not always work. In an example such as
largeRecord defaultPureScript [d|
data SomeRecord = MkRecord { field1 :: Int, field2 :: Bool }
|]
foo :: SomeRecord
foo = [lr| MkRecord { field1 = 5, field2 = True } |]the call to largeRecord and the definition of foo is considered to be a
single binding group (not entirely sure why). Both the largeRecord splice
and the lr quasi-quote are now run before typechecking, which is why when
we get to the lr quasi-quote, the MetadataOf instance is not yet
available, even though it has been generated.
One work-around is to insert an empty splice
largeRecord defaultPureScript [d|
data SomeRecord = MkRecord { field1 :: Int, .. }
|]
$(return [])
foo :: SomeRecord
foo = [lr| MkRecord { field1 = 5, .. } |]That works (and we previously did that, giving that empty splice a name
endOfBindingGroup), but requiring this is bad for useability of the lib.
Most users probably don't know what binding groups even are, much less want
to think about the scope of each binding group: that's a task for ghc.
Therefore, in addition to being able to parse the MetadataOf instance, we
also maintain our own environment, mapping constructor names to record info
(see getRecordInfo). The largeRecord splice adds entries into
this environment, and the lr quasi-quoter consults this environment.
The contents of this environment are ephemeral, of course, and certainly not
stored as part of interface files, so this is merely a backup for when the
MetadataOf information is not available.