在Haskell中处理全局标志的正确方法 [英] Proper way to treat global flags in Haskell

查看:218
本文介绍了在Haskell中处理全局标志的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常需要创建一个核心函数,这个函数在很多地方以某种方式配置 - 也就是说,它可以根据命令行开关使用算法A或算法B;或者让它打印非常详细的信息到stdout,如果设置了'debug'标志。



我应该如何实现这样的全局标记?



我看到4个选项,它们都不是很好。

1)从函数中读取命令行参数 - bad,因为这需要IO monad和核心计算函数都是纯的,所以我不想在那里得到IO;
$ b 2)从main / IO传递一个参数all到需要改变行为的'leaf'函数的方式 - 完全无法使用,因为这意味着要在不同的模块中改变十几个不相关的函数来传递这个参数,并且我想多次尝试这样的配置选项而不改变包装代码每次;

3)使用unsafePerformIO获得一个真正的全局变量 - 感觉丑陋和矫枉过正这样一个简单的问题;



4)在函数中间,有两个选项的代码,并对其中一个选项发表评论。或者有函数do_stuff_A和do_stuff_B,并根据全局函数'needDebugInfo = True'的说法改变它们中的哪一个被调用。这就是我现在为debuginfo所做的,但不能在没有重新编译的情况下进行更改,它不应该是最好的可用方法...



我不需要或想要全局可变状态 - 我想要一个简单的全局标志,它在运行时不可变,但可以在程序启动时以某种方式设置。是否有任何选择?

我们的新 HFlags 库正是为此而设计的。



如果您想查看示例用法,请查看以下内容:



https: //github.com/errge/hflags/blob/master/examples/ImportExample.hs



https://github.com/errge/hflags/blob/master/examples/X/B.hs

https://github.com/errge/hflags/blob/master/examples/X/Y_Y/A.hs



没有任何参数模块之间需要传递,并且可以使用简单的语法定义新的标志。它在内部使用unsafePerformIO,但我们认为它以一种安全的方式实现了这一点,您不必担心这一点。



有一篇博文这个东西在: http://blog.risko.hu/2012/04 /ann-hflags-0.html


I often need to make a core function that's used in many places somehow configurable - i.e., it may use either algorithm A or algorithm B depending on a command-line switch; or have it print extra-verbose information to stdout if a 'debug' flag is set somehow.

How should I implement such global flags?

I see 4 options, all of them aren't really good.

1) Read command-line arguments from the function - bad, because that needs IO monad and the core calculation functions all are pure, I don't want to get IO in there;

2) Pass a parameter from main/IO all the way through to the 'leaf' function which needs to change behavior - completely unusable, as that means changing a dozen of unrelated functions in different modules to pass this parameter, and I want to try out such configuration options multiple times without changing the wrapping code every time;

3) Use unsafePerformIO to get a true global variable - feels ugly and overkill for such a simple issue;

4) Right in the middle of the funcion have code for both options and comment one of them out. Or have functions do_stuff_A and do_stuff_B, and change which one of them is called depending on what a global function 'needDebugInfo=True' says. That's what I'm doing now for the debuginfo, but it can't be changed w/o recompile, and it shouldn't really be the best available way...

I don't need or want global mutable state - I want to have a simple global flag that's immutable at runtime but can be somehow set when the program is launched. Are there any options ?

解决方案

Our new HFlags library is exactly for this.

If you would like to see an example usage like your example, look into this:

https://github.com/errge/hflags/blob/master/examples/ImportExample.hs

https://github.com/errge/hflags/blob/master/examples/X/B.hs

https://github.com/errge/hflags/blob/master/examples/X/Y_Y/A.hs

No kind of parameter passing is needed between the modules, and you can define new flags with an easy syntax. It uses unsafePerformIO internally, but we think that it does that in a safe way, and you won't have to concern yourself with that.

There is a blog post about this stuff at: http://blog.risko.hu/2012/04/ann-hflags-0.html

这篇关于在Haskell中处理全局标志的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆