addTopDecls fails with typed Template Haskell
The following untyped Template Haskell works as expected:
--- AddTopDecls.hs ---
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE QuasiQuotes #-}
module AddTopDecls where
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
importDoubleToDouble :: String -> ExpQ
importDoubleToDouble fname = do
n <- newName fname
d <- forImpD CCall unsafe fname n [t|Double -> Double|]
addTopDecls [d]
varE n
--- Main.hs ---
{-# LANGUAGE TemplateHaskell #-}
module Main where
import AddTopDecls
main :: IO ()
main = do
let sin' = $(importDoubleToDouble "sin")
cos' = $(importDoubleToDouble "cos")
--
print (sin' 0)
print (cos' pi)
However it fails if I convert to the equivalent typed version:
--- AddTopDecls.hs ---
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE QuasiQuotes #-}
module AddTopDecls where
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
importDoubleToDouble :: String -> Q (TExp (Double -> Double))
importDoubleToDouble fname = do
n <- newName fname
d <- forImpD CCall unsafe fname n [t|Double -> Double|]
addTopDecls [d]
unsafeTExpCoerce (varE n)
--- Main.hs ---
{-# LANGUAGE TemplateHaskell #-}
module Main where
import AddTopDecls
main :: IO ()
main = do
let sin' = $$(importDoubleToDouble "sin")
cos' = $$(importDoubleToDouble "cos")
--
print (sin' 0)
print (cos' pi)
With the error:
> ghci Main.hs -ddump-splices
GHCi, version 8.2.0.20170404: http://www.haskell.org/ghc/ :? for help
[1 of 2] Compiling AddTopDecls ( AddTopDecls.hs, interpreted )
[2 of 2] Compiling Main ( Main.hs, interpreted )
Main.hs:9:19-44: Splicing expression
importDoubleToDouble "sin" ======> sin_a4s2
Main.hs:1:1: Splicing top-level declarations added with addTopDecls
======>
foreign import ccall unsafe "sin" Main.sin :: Double -> Double
Main.hs:9:19: error:
• GHC internal error: ‘sin_a4s2’ is not in scope during type checking, but it passed the renamer
tcl_env of environment: [a4dl :-> Identifier[sin'::t1, TopLevelLet [] False],
a4dm :-> Identifier[cos'::t1, TopLevelLet [] False],
r4cW :-> Identifier[main::IO (), TopLevelLet]]
• In the expression: sin_a4s2
In the result of the splice:
$importDoubleToDouble "sin"
To see what the splice expanded to, use -ddump-splices
In the Template Haskell splice $$(importDoubleToDouble "sin")
|
9 | let sin' = $$(importDoubleToDouble "sin")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
Tested with 7.10.3, 8.0.2, and 8.2.0-rc1.
Unfortunately I can't use untyped TH in my real use case, so if you have any suggestions for a workaround that would also be great.
Trac metadata
Trac field | Value |
---|---|
Version | 8.2.1-rc1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Template Haskell |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |