作为将用户输入的字符串动态加载为Haskell源代码的程序的一部分,我想在编译之前对用户的输入进行一些预处理。
我希望能够做的事情之一是搜索特定功能事件的源并为它们添加额外的参数。因此,例如,我可能想要出现所有:
addThreeNumbers 3 5
成为:
addThreeNumbers 3 5 10
完成此类行为的最佳方法是什么?它是否足够复杂以保证在GHC API / Template Haskell中使用函数操作某种抽象语法树?或者这是否可以通过某种Haskell预处理/解析库来实现?如果是这样,你会推荐哪些图书馆和资源?
答案 0 :(得分:1)
Ghc 7.6 qualified imports,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操作。用户甚至不需要更改任何函数调用或模块导入,只需在其名称中添加“internal”即可。
能够无缝地包装模块接口也意味着您可以更改导入模块的植入,而无需触及包/模块代码或您正在使用的现有代码库;你只需要做一个中间层。
编辑对问题的回复:
当然你可以让ghc-api让你做到这一切,但是要复杂得多,我希望有更少的例子漂浮在周围,我似乎看到更多的人在成功故事中遇到困难。< / p>
据我所知,GHC-API是唯一一个与GHC兼容代码完全兼容的API,但它相当复杂,文档记录较少,更有可能从GHC版本更改为GHC版本,或者至少没有从我有限的经验来看,它会是一样的。我建议在中间放置一个模块,因为看起来最快的是获得良好的测试覆盖率,获取最少的新知识并满足我从你的问题中挑选出来的要求。