Haskell表达式上的Alpha转换

Haskell表达式上的Alpha转换,haskell,lambda-calculus,haskell-src-exts,Haskell,Lambda Calculus,Haskell Src Exts,给定一个Haskell表达式,我想执行alpha转换,即重命名一些非自由变量 我已经开始为此实现我自己的函数,该函数在haskell src EXT Exp树上工作,但是它出乎意料地不平凡,所以我不禁想知道,是否有一个现成的易于使用的库解决方案用于这种源代码转换?理想情况下,它应该与haskell src exts集成 这是“废弃样板文件”样式的通用库所面临的问题之一 我最熟悉的是,但我目前还没有安装它,所以我将使用中的(非常类似的)功能。这里的想法是,它使用Data.Data.Data(这是有

给定一个Haskell表达式,我想执行alpha转换,即重命名一些非自由变量


我已经开始为此实现我自己的函数,该函数在haskell src EXT Exp树上工作,但是它出乎意料地不平凡,所以我不禁想知道,是否有一个现成的易于使用的库解决方案用于这种源代码转换?理想情况下,它应该与haskell src exts集成

这是“废弃样板文件”样式的通用库所面临的问题之一

我最熟悉的是,但我目前还没有安装它,所以我将使用中的(非常类似的)功能。这里的想法是,它使用
Data.Data.Data
(这是有史以来最好的限定名称)和相关类以多态方式执行泛型操作

下面是最简单的例子:

alphaConvert :: Module -> Module
alphaConvert = template %~ changeName

changeName :: Name -> Name
changeName (Ident n) = Ident $ n ++ "_conv"
changeName n = n
(~)
操作符来自
lens
,它只意味着将函数
changeName
应用于通用遍历
模板所选择的所有内容。这样做的目的是找到每个字母数字标识符,并将
\u conv
附加到其中。在自己的源上运行此程序会产生以下结果:

module AlphaConv where
import Language.Haskell.Exts
import Control.Lens
import Control.Lens.Plated
import Data.Data.Lens

instance Plated_conv Module_conv
main_conv
  = do ParseOk_conv md_conv <- parseFile_conv "AlphaConv.hs"
       putStrLn_conv $ prettyPrint_conv md_conv
       let md'_conv = alphaConvert_conv md_conv
       putStrLn_conv $ prettyPrint_conv md'_conv

alphaConvert_conv :: Module_conv -> Module_conv
alphaConvert_conv = template_conv %~ changeName_conv

changeName_conv :: Name_conv -> Name_conv
changeName_conv (Ident_conv n_conv)
  = Ident_conv $ n_conv ++ "_conv"
changeName_conv n_conv = n_conv
模块AlphaConv其中
导入语言.Haskell.Exts
进口管制.镜头
进口管制
导入Data.Data.Lens
实例转换模块转换
主变压器
=do ParseOk_conv md_conv Module_conv
alphaConvert\u conv=模板\u conv%~changeName\u conv
更改名称\u conv::名称\u conv->名称\u conv
变更名称变更(标识变更n变更)
=Ident_conv$n_conv++“_conv”
更改名称\u conv n\u conv=n\u conv
这不是很有用,因为它不区分本地绑定的标识符和在外部范围中定义的标识符(例如导入的标识符),但它演示了基本思想

lens
可能看起来有点吓人(它的功能远不止此);您可能会发现
uniplate
或其他库更容易接近


解决实际问题的方法是多部分转换,首先选择要在其中进行alpha转换的子表达式,然后对这些子表达式使用转换来修改要更改的名称。

泛型解决一个可能的问题(使用AST),而不是另一个问题(确定alpha等价性、避免捕获等)。我把这个问题解释为更多关于后者的问题,因为后者有一些库(
unbound
bound
),但我不知道它们是否可以很容易地应用于
haskell src exts
+1以获得良好的写作效果,然而,我不确定这是否是我想要的。我不熟悉您提到的库,但我真正想要避免的不是太多的样板文件,而是真正的逻辑(在大部分情况下识别绑定名与自由名).你可能会发现ekmett的图书馆很有帮助