Proper way to treat global flags in Haskell

后端 未结 4 843
天涯浪人
天涯浪人 2021-02-07 12:19

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; o

4条回答
  •  刺人心
    刺人心 (楼主)
    2021-02-07 13:12

    You can use the Reader monad to get the same effect as passing a parameter around everywhere. Applicative style can make the overhead fairly low compared to normal functional code, but it can still be pretty awkward. This is the most common solution to the configuration problem, but I don't find it terribly satisfactory; indeed, passing the parameter around explicitly is often less ugly.

    An alternative is the reflection package, which lets you pass around common configuration data like this around through typeclass contexts, which means none of your code has to change to plumb the additional value, only the types. Basically, you add a new type parameter to every input/result type in your program, so that everything operating within the context of a certain configuration has the type that corresponds to that configuration in its type. That type stops you accidentally mixing values using multiple configurations, and gives you access to the associated configuration at runtime.

    This avoids the overhead of writing everything in applicative style, while still being safe, and allowing you to mix multiple configurations. It's a lot simpler than it sounds; here's an example.

    (Full discloure: I've worked on the reflection package.)

提交回复
热议问题