1

作为将用户输入的字符串动态加载为 Haskell 源代码的程序的一部分,我想在编译之前对用户的输入进行一些预处理。

我想做的一件事是搜索特定函数出现的源并为它们添加一个额外的参数。因此,例如,我可能想要所有出现的:

addThreeNumbers 3 5

成为:

addThreeNumbers 3 5 10

完成这种行为的最佳方法是什么?是否足够复杂以保证使用 GHC API / Template Haskell 中的函数来操作某种抽象语法树?或者这是否可以通过某种 Haskell 预处理/解析库来完成?如果是这样,您会推荐哪些图书馆和资源?

4

1 回答 1

1

Ghc 7.6限定导入、ghc-pkg hide 和 ghc 的 -package 选项允许您在导入文件和导入文件之间无缝添加一层。

例子:

使用您自己的 Data.Char 创建一个包,使用标准 .cabal 文件和 cabal 安装。

{-# language PackageImports #-}                                                  

module Data.Char (                                                               
      toUpper                                                                    
    , Char                                                                       

    , String                                                                     
    -- ...  Export every else from "Base" Data char because the limitation of
    --     the current export facility you can not use
    --     module Data.Char hiding (toUpper)
    ) where                                                                      

import "base" Data.Char hiding (toUpper)                                         
import qualified "base" Data.Char as OldChar                                     

toUpper :: Char -> IO Char                                                       
toUpper c = do                                                                   
    print "Oh Yeahhhhhhhhh"                                                      
    return $ OldChar.toUpper c

隐藏基本包ghc-pkg hide base——在这种情况下隐藏了许多模块,如果需要,您需要将它们全部包装起来。

> ghci -XNoImplicitPrelude --  We need language flag because the Prelude is in
                           -- base and I did not make a wrapped Prelude
ghci> import Data.Char
ghci> toUpper 'c'  -- The wrapped function
"Oh Yeahhhhhhhhh"
'C'
ghci> isSpace ' '  -- The unwrapped normal Data.Char function
True

现在您可以使用模板 Haskell 来包装您的函数并调用您需要获取外部信息的任何 IO 操作。用户甚至不需要更改任何函数调用或模块导入,只需在名称中添加“内部”即可。

能够无缝地封装模块接口还意味着您可以更改导入模块的植入,而无需接触包/模块代码或您正在使用的现有代码库;你只需要做一个中间层。

编辑对问题的回复:

当然可以,ghc-api 可以让您完成所有这些工作,但是要复杂得多,比我想要的例子更少,而且我似乎看到更多人在使用它时遇到困难,然后是成功案例。

  • 用于评估代码提示
  • 建议使用插件来动态加载模块
  • haskell-src-ext 建议用于解析和更改代码。这就是style-haskell用来对代码进行小修改的方法,是你最好的选择。据报道,它涵盖了 Haskell 2010 的大部分(全部?),以及许多但不是所有 GHC 扩展,如果您不喜欢我提供的第一个解决方案,它可能是您最好的选择。

据我所知,GHC-API 是唯一一个与 GHC 兼容代码完全兼容的代码,但要复杂得多,文档记录较少,而且更有可能从 GHC 版本更改为 GHC 版本,或者至少没有承诺会根据我有限的经验,是一样的。我建议将一个模块放在中间,因为它似乎是最快的获得良好的测试覆盖率,需要最少的新知识并满足我从你的问题中挑选出来的要求。

于 2013-01-24T02:34:08.250 回答