如何分析用 Cabal 构建的 TemplateHaskell?

How to profile TemplateHaskell built with Cabal?

完整项目位于 https://github.com/ysangkok/cabal-profiling-issue

该项目包含 cabal init 生成的脚手架。我现在将粘贴最有趣的源代码片段。

Main.hs 我有:

newtype Wrapper = Wrapper Int

deriveConvertible ''Wrapper ''Int

TH.hs 我有:

import            Data.Convertible

deriveConvertible :: TH.Name -> TH.Name -> TH.Q [TH.Dec]
deriveConvertible newType otherType = do
  Just newCon <- TH.lookupValueName (TH.nameBase newType)
  v <- TH.newName "v"

  [d|
    instance Convertible $(TH.conT newType) $(TH.conT otherType) where
      safeConvert $(TH.conP newCon [TH.varP v]) = Right $(TH.varE v)

    instance Convertible $(TH.conT otherType) $(TH.conT newType) where
      safeConvert source = Right ($(TH.conE newCon) source)

    |]

但是如果我将 profiling: true 放入 cabal.project 和 运行 cabal build 以及 GHC 8.6.5 和 Cabal 3.4.0.0(使用 ghcup 安装),我得到:

    Failed to load interface for 'Data.Convertible.Base'
    Perhaps you haven't installed the profiling libraries for package 'convertible-1.1.1.0'?

代码有什么问题,为什么它在没有分析的情况下编译,但在启用时却失败了?

关于编译包含用于分析的 TH 代码的多模块程序,这是一个已知问题,请参阅文档中的相关部分:

This causes difficulties if you have a multi-module program containing Template Haskell code and you need to compile it for profiling, because GHC cannot load the profiled object code and use it when executing the splices.

作为解决方法,只需将 TemplateHaskell 放入 test.cabal、

中的 other-modules
     other-extensions: TemplateHaskell

然后使用分析(即使用 cabal build --enable-library-profiling)进行构建,一切都会好起来的。

有关 other-modules 部分中为什么需要 TemplateHaskell 的更多详细信息,请参阅 https://github.com/haskell/cabal/issues/5961