title: How to circumvent GHC Stage Restriction?
body: <p>I am writing a code generator whose output depends on datatype fields description which is stored in their class instances. However, I cannot find how to run a function with a TH-generated argument.</p>
  
  <pre><code>{-# LANGUAGE TemplateHaskell, ScopedTypeVariables #-}
  module Generator where
  import Language.Haskell.TH
  import Language.Haskell.TH.Syntax
  
  data Description = Description String [Description] deriving Show
  
  class HasDescription a where
    getDescription :: a -&gt; Description
  
  instance HasDescription Int where
    getDescription _ = Description "Int" []
  
  instance (HasDescription a, HasDescription b) =&gt; HasDescription (a, b) where
    getDescription (_ :: (a, b)) = Description "Tuple2" [getDescription (undefined :: a), getDescription (undefined :: b)]
  
  -- | creates instance of HasDescription for the passed datatype changing descriptions of its fields
  mkHasDescription :: Name -&gt; Q [Dec]
  mkHasDescription dName = do
    reify dName &gt;&gt;= runIO . print
    TyConI (DataD cxt name tyVarBndr [NormalC cName types] derives) &lt;- reify dName
    -- Attempt to get description of data to modify it.
    let mkSubDesc t = let Description desc ds = getDescription (undefined :: $(return t)) in [| Description $(lift $ desc ++ "Modified") $(lift ds) |]
  
    let body = [| Description $(lift $ nameBase dName) $(listE $ map (mkSubDesc . snd) types) |]
    getDescription' &lt;- funD 'getDescription [clause [wildP] (normalB body) []]
    return [ InstanceD [] (AppT (ConT ''HasDescription) (ConT dName)) [getDescription'] ]
  </code></pre>
  
  <p>When another module tries to use Generator</p>
  
  <pre><code>{-# LANGUAGE TemplateHaskell, ScopedTypeVariables #-}
  import Generator
  
  data MyData = MyData Int Int
  
  mkHasDescription ''MyData
  
  {- the code I want to generate
  instance HasDescription MyData where
    getDescription _ = Description "MyData" [Description "IntModified" [], Description "IntModified" []]
  -}
  </code></pre>
  
  <p>there appears an error</p>
  
  <pre><code>Generator.hs:23:85:
  GHC stage restriction: `t'
    is used in a top-level splice or annotation,
    and must be imported, not defined locally
  In the first argument of `return', namely `t'
  In the expression: return t
  In an expression type signature: $(return t)
  </code></pre>
  
  <p>edit:</p>
  
  <p>When asking I thought that the issue appeared just because I just did not grasp something crucial in TH and it could be resolved with moving some functions to the other modules.</p>
  
  <p>If it is impossible to generate precomputed data as in example from the question, I would like to learn more about the theoretical restrictions of TH.</p>