「コードの匂い」という言葉は嫌いですが、これ以上正確なものは思いつきません。
コンパイラの構築、言語設計、関数型プログラミング (コンパイラは Haskell で書かれています) について学ぶために、空き時間にWhitespaceに高水準言語とコンパイラを設計しています。
コンパイラのコード生成フェーズでは、構文ツリーをたどる際に「状態」のようなデータを維持する必要があります。たとえば、フロー制御ステートメントをコンパイルするとき、ジャンプ先のラベルに一意の名前を生成する必要があります (ラベルは、渡され、更新され、返されたカウンターから生成され、カウンターの古い値を二度と使用してはなりません)。もう 1 つの例は、構文ツリーでインライン文字列リテラルに遭遇した場合です。それらはヒープ変数に永続的に変換する必要があります (ホワイトスペースでは、文字列はヒープに格納するのが最適です)。現在、これを処理するためにコード生成モジュール全体を状態モナドにラップしています。
コンパイラを書くことは関数型パラダイムに適した問題だと言われたことがありますが、私はこれを C で設計するのとほぼ同じ方法で設計していることに気付きました (C は実際にはどの言語でも書くことができます。 Haskell と状態モナド)。
Haskell 構文を使用した C ではなく、Haskell で (むしろ関数型パラダイムで) 考える方法を学びたいです。状態モナドの使用を本当に排除/最小化しようとするべきですか、それとも正当な機能的な「設計パターン」ですか?