title: Using Template Haskell, how can I splice the same type into multiple locations?
body: <p>I'm defining instances of classes from <a href="http://hackage.haskell.org/package/vector-space" rel="noreferrer">vector-space</a> for the <a href="http://hackage.haskell.org/package/OpenGL" rel="noreferrer">OpenGL</a> types, and to spare my typing muscles, I want to use Template Haskell to write a bunch of the instances for me.</p>
  
  <p>I started out small by defining function to derive instances for <code>AdditiveGroup</code>:</p>
  
  <pre><code>{-# LANGUAGE FlexibleInstances #-}
  {-# LANGUAGE TemplateHaskell #-}
  {-# LANGUAGE TypeFamilies #-}
  module Data.VectorSpace.OpenGL.TH where
  
  import Control.Applicative
  import Control.Monad
  import Data.AdditiveGroup
  import Data.VectorSpace
  
  import Language.Haskell.TH
  
  deriveScalarAdditive ts = concat &lt;$&gt; forM (map conT ts) (\t -&gt; [d| 
      instance AdditiveGroup $t where zeroV = 0; (^+^) = (+); negateV = negate
    |])
  </code></pre>
  
  <p>This works fine, but note that I'm only splicing <code>$t</code> once into the Oxford brackets. Now, the function to derive <code>VectorSpace</code> instances:</p>
  
  <pre><code>deriveScalarVectorSpace ts = concat &lt;$&gt; forM (map conT ts) (\t -&gt; [d|    
      instance VectorSpace $t where type Scalar $t = $t; (*^) = (*)
    |])
  </code></pre>
  
  <p>But, this barfs:</p>
  
  <pre><code>Type indexes must match class instance head
  Found `t_tt' but expected `t_ts'
  In the associated type instance for `Scalar'
  In the instance declaration for `VectorSpace $t'
  In the Template Haskell quotation
    [d| instance VectorSpace $t where
            type instance Scalar $t = $t
            { *^ = (*) } |]
  </code></pre>
  
  <p>The difference between <code>t_ts</code> and <code>t_tt</code> in the error tells me that TH is creating a new, unique name every time I splice in <code>$t</code>, when of course the definition will only work if those types are the same. </p>
  
  <p>Is there a way to get the behavior I want with Oxford brackets, or will I have to fall back to good old lexical scope and the <code>Language.Haskell.TH</code> combinators? I know this would probably be easier with the CPP, but I want to take this opportunity to learn some TH.</p>