如何在TH接头中复制'name的行为 [英] How to replicate the behaviour of 'name in a TH splice
问题描述
考虑此Haskell文件:
Consider this Haskell file:
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -fplugin Test.Inspection.Plugin #-}
module Text (main) where
import Test.Inspection
import Data.Text as T
import Data.Text.Encoding as E
import Data.ByteString (ByteString)
import Language.Haskell.TH
toUpperString :: String -> String
toUpperString = T.unpack . T.toUpper . T.pack
toUpperBytestring :: ByteString -> String
toUpperBytestring = T.unpack . T.toUpper . E.decodeUtf8
do Just n <- lookupValueName "toUpperString"
inspect $ n `hasNoType` ''T.Text
inspect $ 'toUpperBytestring `hasNoType` ''T.Text
main :: IO ()
main = return ()
它使用模板Haskell定义由GHC插件在检验测试中测试的测试义务.
It uses Template Haskell to define test obligations which are tested by the GHC plugin in inspection-testing.
在引擎盖下,检验测试通过注释中的模板Haskell名称,并使用thNameToGhcName
将其转换为Core名称,然后尝试在当前模块中找到该名称.
Under the hood, inspection testing passes a Template Haskell name in an annotation, and converts it to to a Core name using thNameToGhcName
, and then tries to find this name in the current module.
如果我使用'foo
创建模板Haskell名称,此方法就很好,但是如果使用lookupValueName
,则失败.
This works fine if I create a template Haskell name using 'foo
, but it fails if I use lookupValueName
.
- 它们为什么不同?
- 当我有一个字符串时,如何重新创建
'foo
的行为?
- Why are they different?
- How can I recreate the behavior of
'foo
when I have a string?
(为什么我不仅仅使用'foo
?因为我想动态创建义务,所以我有模板Haskell代码定义了许多这样的功能和义务.)
(Why do I not just use 'foo
? Because I want to dynamically create obligations, so I have Template Haskell code that defines many such functions and obligations.)
推荐答案
在这种情况下,问题并不在于'foo
与lookupValueName
返回的Name
不同,而是使用'foo
在模块的整个编译过程中,foo
保持活动状态,而lookupValueName "foo"
则不保持活动状态.然后,GHC删除"foo"
的绑定和对其进行检查测试的行程.
The problem in this case is not so much that the Name
returned by 'foo
vs. lookupValueName
is different, but that using 'foo
keeps foo
alive throughout the compilation of the module, while lookupValueName "foo"
does not. Then GHC removes the binding of "foo"
and inspection-testing trips over it.
并且确实从模块中删除了导出列表,从而使所有顶级绑定都存在,从而使问题消除了.
And indeed removing the export list from the module, which keeps all top-level bindings around, makes the problem go away.
这篇关于如何在TH接头中复制'name的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!