Splice type signature in haskell template

I am trying to create a type signature for a function in a haskell template. Is there an easy way to do this?

I did some workarounds to solve this at the same time, but it should be easier, right?

-- TH.hs module Lib.TH (mkFunction) where import Language.Haskell.TH mkFunction n = do let name = mkName n [d| $( ... ) :: Integer -> Integer $(varP name) = \x -> x + 2|] -- Other.hs import TH mkFunction "test" 

What should I write in $( ... ) above? Everything I tried leads to

 Invalid type signature: ... :: Integer -> Integer Should be of form <variable> :: <type> 
+5
source share
2 answers

I am not a TH expert, but I found a way by delving into the documents and watching for type errors.

 import Language.Haskell.TH import Control.Applicative ((<$>)) mkFunction n = do let name = mkName n [d| $( return . SigD name <$> [t| Integer -> Integer |] ) $(varP name) = \x -> x + 2 |] 

I do not know if there is a cleaner way.

NOTE works on 7.8.3, but not 7.10.2 .: - (

+3
source

I do not think (I guess) that there is a way to associate a name in a signature of type Template Haskell (for GHC ≤ 7.10). To still use quasi-cycling, you can try to process the AST after that to indicate the name where it is needed (and leave it unchanged):

 setName :: Name -> DecsQ -> DecsQ setName = fmap . map . sn where sn n (SigD _ t) = SigD nt sn n (ValD (VarP _) xy) = ValD (VarP n) xy sn _ d = d mkFunction n = setName (mkName n) [d| n :: Integer -> Integer n = \x -> x + 2 |] 

This has been tested on GHC 7.10 and is likely to work with past and future versions of GHC with minor modifications.

To what extent is it less or more verbose than directly spelling AST. This will depend on the frequency that you record as ads and the complexity of the cited code.

The above setName function setName obviously be violated if you use it in an ad with multiple functions (or recursive functions). To handle this, you could write a reName function in the same vein.

+1
source

All Articles