问题
Suppose I define my own annotation type:
{-# LANGUAGE DeriveDataTypeable #-}
module Def where
import Data.Data
data MyAnn = MyAnn Int deriving (Show, Typeable, Data)
and some Template Haskell function to access it:
module TH where
import Def
import Language.Haskell.TH.Syntax
myAnn :: Name -> Q Exp
myAnn name = do
[MyAnn x] <- reifyAnnotations (AnnLookupName name)
lift x
I would now like to use it like this:
{-# LANGUAGE TemplateHaskell #-}
module Client where
import Def
import TH
x :: ()
x = ()
{-# ANN x (MyAnn 42) #-}
y :: Int
y = $(myAnn 'x)
But this fails because the myAnn
invocation in the definition of y
gets an empty list from reifyAnnotations
.
It works if I split Client
like this:
module Client1 where
import Def
x :: ()
x = ()
{-# ANN x (MyAnn 42) #-}
{-# LANGUAGE TemplateHaskell #-}
module Client2 where
import Client1
import TH
y :: Int
y = $(myAnn 'x)
Is there a way to get something like the monolithic Client
module to work?
回答1:
This seems to be expected behavior according to the docs:
Accordingly, the type environment seen by
reify
includes all the top-level declarations up to the end of the immediately preceding declaration group, but no more.
An effective workaround for your problem is to force the start of a separate declaration group by including an empty top-level declaration splice, i.e. just
$(return [])
来源:https://stackoverflow.com/questions/33562244/retrieving-annotations-from-the-same-module