diff options
author | parsonsmatt <parsonsmatt@gmail.com> | 2021-04-29 11:17:14 -0400 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-05-29 05:05:18 -0400 |
commit | 6412bf6e1e8c70ae96203190f460be243d961c59 (patch) | |
tree | 6f66413909ec04cc95885731861f171f24622a22 /libraries | |
parent | 28e0dca2e93dabee88f28ce38282dbcb8c62ab99 (diff) | |
download | haskell-6412bf6e1e8c70ae96203190f460be243d961c59.tar.gz |
Add `newDeclarationGroup` and provide documentation in reifyInstances and isInstance
Diffstat (limited to 'libraries')
-rw-r--r-- | libraries/template-haskell/Language/Haskell/TH/Syntax.hs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs index d3c5a5eb45..4e0ceb4eef 100644 --- a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs +++ b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs @@ -568,6 +568,60 @@ This works even if there's no explicit signature and the type or kind is inferre reifyType :: Name -> Q Type reifyType nm = Q (qReifyType nm) +{- | Template Haskell is capable of reifying information about types and +terms defined in previous declaration groups. Top-level splices break up +declaration groups. + +For an example, consider this code block. We define a datatype @X@ and +then try to call 'reify' on the datatype. + +@ +module Check where + +data X = X + deriving Eq + +$(do + info <- reify ''X + runIO $ print info + ) +@ + +This code fails to compile, noting that @X@ is not in scope at the site of 'reify'. We can fix this by creating a new declaration group using an empty top-level splice: + +@ +data X = X + deriving Eq + +$(pure []) + +$(do + info <- reify ''X + runIO $ print info + ) +@ + +We provide 'newDeclarationGroup' as a means of documenting this behavior +and providing a name for the pattern. + +Since top level splices infer the presence of the @$( ... )@ brackets, we can also write: + +@ +data X = X + deriving Eq + +newDeclarationGroup + +$(do + info <- reify ''X + runIO $ print info + ) +@ + +-} +newDeclarationGroup :: Q [Dec] +newDeclarationGroup = pure [] + {- | @reifyInstances nm tys@ returns a list of visible instances of @nm tys@. That is, if @nm@ is the name of a type class, then all instances of this class at the types @tys@ are returned. Alternatively, if @nm@ is the name of a data family or type family, @@ -585,6 +639,10 @@ instance heads which unify with @nm tys@, they need not actually be satisfiable. There is one edge case: @reifyInstances ''Typeable tys@ currently always produces an empty list (no matter what @tys@ are given). + +An instance is visible if it is imported or defined in a prior top-level +declaration group. See the documentation for 'newDeclarationGroup' for more details. + -} reifyInstances :: Name -> [Type] -> Q [InstanceDec] reifyInstances cls tys = Q (qReifyInstances cls tys) @@ -625,6 +683,10 @@ reifyConStrictness :: Name -> Q [DecidedStrictness] reifyConStrictness n = Q (qReifyConStrictness n) -- | Is the list of instances returned by 'reifyInstances' nonempty? +-- +-- If you're confused by an instance not being visible despite being +-- defined in the same module and above the splice in question, see the +-- docs for 'newDeclarationGroup' for a possible explanation. isInstance :: Name -> [Type] -> Q Bool isInstance nm tys = do { decs <- reifyInstances nm tys ; return (not (null decs)) } |