不純な言語は、特に多くの機能的なトリックがコピーされた今、原則として、より馴染みのある命令型言語と実際には違いはありません。異なるのはスタイル-問題の解決方法です。
Haskellを純粋なものとして数えるか、IOモナドを不純なものとして数えるかに関わらず、Haskellスタイルはこのスタイルの極端な形であり、学ぶ価値があります。
Haskell IOモナドは、(もちろん)モナドの数学的理論から派生しています。しかし、命令型プログラマにとっては、モナドに逆戻りする方法がより理にかなっていると思います。
フェーズ1-純粋な関数型言語は、結果として大きな文字列値を簡単に返すことができます。この大きな文字列は、いくつかの要件指定パラメータから純粋に機能的な方法で導出された命令型プログラムのソースコードになります。次に、コードジェネレーターを実行する「上位」コンパイラーを構築し、生成されたコードを命令型言語コンパイラーに自動的にフィードします。
フェーズ2-テキストソースコードを生成するのではなく、厳密に型指定された抽象構文ツリーを生成します。命令型コンパイラは「上位」コンパイラに吸収され、ASTをソースコードとして直接受け入れます。これは、Haskellの機能に非常に近いものです。
しかし、これはまだ厄介です。たとえば、コード生成フェーズで評価される関数と、生成されたプログラムの実行時に実行される関数の2種類の関数があります。C ++の関数とテンプレートの区別に少し似ています。
したがって、フェーズ3では、2つを同じにします。同じ構文の同じ関数は、「コード生成」中に部分的に評価されるか、完全に評価されるか、まったく評価されません。さらに、再帰を支持して、すべてのループ構造ASTノードを破棄します。実際、特別な種類のデータとしてのASTノードの考えは完全に捨ててください。「リテラル値」のASTノードを持たず、値だけを持っているなどです。
これはほとんどIOモナドが行うことです-バインド演算子はプログラムを形成するための「アクション」を構成する方法です。特別なものではありません-ただの機能です。多くの式と関数は「コード生成」中に評価できますが、I / O副作用に依存するものは、特別なルールではなく、式。
一般にモナドは単なる一般化です-それらは同じインターフェースを持ちますが、抽象操作を異なる方法で実装するため、命令型コードの記述を評価する代わりに、他の何かを評価します。同じインターフェースを持っているということは、どのモナドを気にせずにモナドに対してできることがいくつかあるということです。
この説明は間違いなく純粋主義者の頭を爆発させますが、私にとっては、Haskellが興味深い理由のいくつかを説明しています。プログラミングとメタプログラミングの境界を曖昧にし、関数型プログラミングのツールを使用して、特別な構文を必要とせずに命令型プログラミングを改革します。
私がC ++テンプレートについて批判しているのは、それらが命令型言語の一種の壊れた純粋な機能的サブ言語であるということです-実行時ではなくコンパイル時に同じ基本機能を評価するには、完全に異なるスタイルを使用して再実装する必要がありますコーディングの。Haskellでは、不純物はそのタイプでそのようにラベル付けする必要がありますが、同じプログラムでメタプログラミングの意味とランタイムの非メタプログラミングの意味の両方でまったく同じ関数を評価できます-強い線はありませんプログラミングとメタプログラミングの間。
そうは言っても、基本的には型(および他のいくつかの要素)が第一級の値ではないため、標準のHaskellができないメタプログラミングの要素がいくつかあります。ただし、これに対処しようとする言語のバリエーションがあります。
Haskellについて私が言ったことの多くは、不純な関数型言語、そして時には命令型言語にも適用できます。Haskellは、このアプローチを取る以外に選択肢がないため、基本的にこの作業スタイルを学ぶことを強制されます。「CをMLで書く」ことはできますが、「CをHaskellで書く」ことはできません-少なくとも内部で何が起こっているかを学ぶことなしではできません。