我正试图将一些代码的执行转移到使用GHC 8编译时
template-haskel-2.11
。代码如下所示:
myThHelper :: FilePath -> Q Exp
myThHelper path =
runIO (compileThatFile path) >>= liftData
这是该代码的简化版本,但它希望传达我的意思 试图做。
注意
liftData
功能,它是template-haskell-2.11
中的新功能,它有望“提升”
表达Data
的任何实例。非常酷,它编译。</ p>
然而,当我像这样使用它时:
main :: IO ()
main = do
let compiled = $(myThHelper "/path/to/my/file/foo.txt")
…
我从编译器收到以下错误消息:
• Can't find interface-file declaration for variable Data.Text.Internal.pack
Probable cause: bug in .hi-boot file, or inconsistent .hi file
Use -ddump-if-trace to get an idea of which file caused the error
• In the first argument of ‘PName’, namely
‘Data.Text.Internal.pack ((:) 'f' ((:) 'o' ((:) 'o' [])))’
In the first argument of ‘Template’, namely
‘PName (Data.Text.Internal.pack ((:) 'f' ((:) 'o' ((:) 'o' []))))’
In the expression:
等。知道发生了什么以及如何解决它?
我通过实验证实,只有当数据类型提升Text
时,问题才会显现。我要打开一个问题。
答案 0 :(得分:6)
这似乎是因为期望dataToQa
显示的函数(toConstr
为"pack"
)与定义数据类型的同一模块。因此Text
正在liftData
中寻找pack
,但Data.Text.Internal
实际上位于pack
。
一种简单的解决方法就是为Text
编写自己的提升功能:
{-# LANGUAGE TemplateHaskell #-}
import qualified Data.Text as T
import Language.Haskell.TH.Syntax
liftText :: T.Text -> Q Exp
liftText txt = AppE (VarE 'T.pack) <$> lift (T.unpack txt)
myThHelper :: FilePath -> Q Exp
myThHelper path =
runIO (compileThatFile path) >>= liftText
如果文字在您想要使用的结构的深处,您可以使用Data.Text
来覆盖类型特定情况的提升功能:
import Data.Data
liftDataWithText :: Data a => a -> Q Exp
liftDataWithText = dataToExpQ (\a -> liftText <$> cast a)