Mar*_*ark 6 haskell template-haskell
我正在尝试转移一些代码的执行,以使用GHC 8和编译时间
template-haskel-2.11
。代码如下:
myThHelper :: FilePath -> Q Exp
myThHelper path =
runIO (compileThatFile path) >>= liftData
Run Code Online (Sandbox Code Playgroud)
这是该代码的简化版本,但希望可以传达我正在尝试做的事情。
注意该
liftData
函数,它是新函数,template-haskell-2.11
并且承诺可以将的任何实例“提升”为表达式Data
。很酷,可以编译。
但是,当我这样使用它时:
main :: IO ()
main = do
let compiled = $(myThHelper "/path/to/my/file/foo.txt")
…
Run Code Online (Sandbox Code Playgroud)
我从编译器收到以下错误消息:
• 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:
Run Code Online (Sandbox Code Playgroud)
等等。有什么想法吗?如何解决?
我通过实验证实,该问题仅在要提升的数据类型包含其中时才会显现出来Text
。我要开一个问题。
这里是。
这似乎是因为dataToQa
希望toConstr
显示的函数("pack"
用于Text
)位于定义数据类型的同一模块中。因此,liftData
正在寻找pack
中Data.Text.Internal
,但pack
实际上是Data.Text
。
一个简单的解决方法是为以下代码编写您自己的Lift函数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
Run Code Online (Sandbox Code Playgroud)
如果文本在要使用的结构中很深,则可以使用dataToExpQ
它来针对特定类型的情况覆盖提升功能:
import Data.Data
liftDataWithText :: Data a => a -> Q Exp
liftDataWithText = dataToExpQ (\a -> liftText <$> cast a)
Run Code Online (Sandbox Code Playgroud)