我想创建一个名为'load'的函数,它从另一个文件导入函数的定义。我知道如何导入模块,但在我的程序中,我希望函数的定义根据使用这个新函数“加载”的模块而改变。有没有办法做到这一点?有没有更好的方法来编写我的程序,这样就没有必要了?
我认为它的类型签名看起来像: load :: String - > IO() 其中string是要加载的模块的名称(并且模块位于同一目录中)。
编辑:感谢所有回复。大多数人都认为这不是做我想做的最好的方法。相反,有没有办法从I / O程序中声明一个全局变量。也就是说,如果我将(函数“thing”)键入String类型的函数中,我想要它。 IO(),我仍然可以在GHCi中键入'thing'来获取分配给它的值...有什么建议吗?
答案 0 :(得分:2)
几乎可以肯定有一种更好的方法来编写程序,这样就没有必要了。但是,如果不了解有关您情况的更多详细信息,很难说出什么。例如,您可以表示每个模块实现为数据类型的通用接口,并让每个模块都使用该实现导出该类型的值。
基本上,加载模块的集合是 static ,编译时属性,因此根据其内容要求程序的行为发生变化是没有意义的。你想写一个图书馆吗?你的用户可能不会欣赏它对他们的导入列表做这样邪恶的魔法:)(并且在这种情况下,如果没有模板Haskell,它可能是不可能的。)
例外情况是,如果您正在尝试实现Haskell工具(例如REPL,IDE等)或尝试插件;即动态加载的Haskell源代码模块,以集成到您的Haskell程序中。首先要尝试的是hint,但你可能会发现你需要更先进的东西;在这种情况下,GHC API可能是你最好的选择。 plugins曾经是这一领域的事实上的标准,但它似乎没有用GHC 7编译;您可能想查看direct-plugins,这是一个类似界面的简化实现。
mueval可能具有相关性;它被设计用于在安全的沙箱中执行Haskell代码的短(一行)代码片段,如lambdabot所使用。
答案 1 :(得分:1)
除非您正在构建Haskell IDE或类似的东西,否则您很可能不需要这个(^ 1)。
但是,如果您这样做,总会有 hint-package ,它允许您将haskell解释器嵌入到您的程序中。这允许您加载haskell模块并在运行时将字符串转换为haskell值。有一个很好的例子,说明如何使用它here
^ 1:如果您正在寻找一种方法来使事物具有多态性,即改变代码中的一些但不是所有定义,那么您可能正在寻找typeclasses。
答案 2 :(得分:0)
关于您的修改,也许您可能对IORef
感兴趣。