找不到变量的inerface文件声明

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。我要开一个问题。


这里是

cch*_*ers 7

这似乎是因为dataToQa希望toConstr显示的函数("pack"用于Text)位于定义数据类型的同一模块中。因此,liftData正在寻找packData.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)

  • @Mark在这种情况下,您可以使用[`dataToExQ`](http://hackage.haskell.org/package/template-haskell-2.11.0.0/docs/Language-Haskell-TH-Syntax.html#v:dataToExpQ) 。我已经更新了答案。 (2认同)