Właściwy sposób traktowania globalnych flag w Haskell

Często muszę stworzyć funkcję rdzenia, która jest używana w wielu miejscach, w jakiś sposób konfigurowalna, tj. Może używać algorytmu A lub algorytmu B w zależności od przełącznika wiersza poleceń; lub niech wypisze dodatkowe informacje do stdout, jeśli flaga „debugowania” jest w jakiś sposób ustawiona.

Jak wdrożyć takie globalne flagi?

Widzę 4 opcje, wszystkie nie są naprawdę dobre.

Odczytaj argumenty wiersza polecenia z funkcji - źle, ponieważ wymaga to monotonu IO, a podstawowe funkcje obliczeniowe są czyste, nie chcę tam umieszczać IO;

Przekazuj parametr z main / IO aż do funkcji „leaf”, która musi zmienić zachowanie - całkowicie bezużyteczna, ponieważ oznacza to zmianę kilkunastu niepowiązanych funkcji w różnych modułach, aby przekazać ten parametr, i chcę wypróbować takie opcje konfiguracji wielokrotnie bez zmiany kodu opakowania za każdym razem;

Posługiwać sięunsafePerformIO aby uzyskać prawdziwą zmienną globalną - czuje się brzydko i przesadza z powodu tak prostego problemu;

W samym środku funkcji masz kod dla obu opcji i skomentuj jeden z nich. Lub mieć funkcje do_stuff_A i do_stuff_B i zmienić, który z nich jest wywoływany w zależności od funkcji globalnejneedDebugInfo=True mówi. To właśnie robię teraz dladebuginfo, ale nie można go zmienić bez rekompilacji i nie powinien to być najlepszy dostępny sposób ...

Nie potrzebuję ani nie chcę globalnego stanu zmiennego - chcę mieć prostą flagę globalną, która jest niezmienna w czasie wykonywania, ale może być w jakiś sposób ustawiona podczas uruchamiania programu. Czy są jakieś opcje?

questionAnswers(4)

yourAnswerToTheQuestion