如何用Template Haskell获取函数列表中函数的名称(无需硬编码)
借助Template Haskell获取函数名称的优雅实现
当然可行,而且有比你找到的更简洁的实现方式。
更优雅的写法
你可以封装一个简单的Template Haskell辅助函数,用来同时生成函数本身和它的名称字符串,然后直接构建列表:
{-# LANGUAGE TemplateHaskell #-} import qualified Module (function1, function2) import Language.Haskell.TH -- 辅助函数:生成 (函数, 函数名称字符串) 的元组表达式 funcWithName :: Name -> Q Exp funcWithName name = [| ($(varE name), $(stringE $ nameBase name)) |] -- 直接生成包含函数和对应名称的列表 functions :: [(a -> b, String)] functions = $(listE $ map funcWithName ['Module.function1, 'Module.function2]) main = do let names = map snd functions print names
代码说明
nameBase name可以直接提取出函数的基础名称字符串(比如'Module.function1会被转换成"function1";如果需要保留模块前缀,改用show name即可得到"Module.function1")funcWithName用拼接表达式的方式,替代了手动构造TupE、VarE的繁琐写法,代码可读性更强- 最后通过
listE把多个元组表达式组合成列表表达式,逻辑清晰直观
仅获取名称列表的简化方案
如果只需要获取函数名称的集合,无需绑定函数本身,可以直接生成名称列表:
{-# LANGUAGE TemplateHaskell #-} import qualified Module (function1, function2) import Language.Haskell.TH functionNames :: [String] functionNames = $(listE $ map (stringE . nameBase) ['Module.function1, 'Module.function2]) main = print functionNames
内容的提问来源于stack exchange,提问作者Fabus1184
相关产品推荐
相关产品推荐

