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?