I have a class called Cls. In one of the instances of Cls, in one of the methods, I want to do some code analysis from within template haskell. I have to run a reify to start this inspection. Full files are included below.
class Cls a where
infixl 6 +.
(+.) :: Num a => v a -> v a -> v a
newtype Evaluate a = Evaluate a
instance Cls Evaluate where
(+.) a b = doSomething $(typesOf '(+.)) a b
typesOf :: Name -> Q Exp
typesOf name = do
_ <- reify name
-- do something
[e|["Double", "Int"]|]
However, at $(typesOf '(+.)), I get the following error:
‘+.’ is not in the type environment at a reify
In the untyped splice: $(typesOf '(+.))
If I compare this to, for example, makeLenses in the Control.Lens library, they do a similar thing. There it works. Which leads me to believe that, somehow, the '(+.) resolves to the function in the current instance declaration instead of the '(+.) in the class declaration.
Is this correct? If so, how do I actually use the class method as an argument to template haskell in this instance (no pun intended)?
{-# LANGUAGE TemplateHaskell #-}
module Main where
import Th
class Cls a where
infixl 6 +.
(+.) :: Num a => v a -> v a -> v a
newtype Evaluate a = Evaluate a
instance Cls Evaluate where
(+.) a b = doSomething $(typesOf '(+.)) a b
-- Below here is not important
doSomething :: [String] -> a -> a
doSomething types a _ = trace (intercalate ", " types) a
main :: IO ()
main = putStrLn "Hello, Haskell!"
{-# LANGUAGE TemplateHaskell #-}
module Th where
import Language.Haskell.TH
typesOf :: Name -> Q Exp
typesOf name = do
_ <- reify name
-- do something
[e|["a", "b"]|]