関数型言語が機能的であるという理由だけで(Haskellのように完全に純粋でさえあるかもしれません!)、その言語で書かれたプログラムが実行されたときに純粋でなければならないという意味ではありません。
たとえば、副作用を処理する場合のHaskellのアプローチは、かなり簡単に説明できます。プログラム全体を純粋にします(つまり、関数は同じ引数に対して常に同じ値を返し、副作用はありません)。関数の戻り値をmain
実行可能なアクションとします。
これを擬似コードで説明しようとすると、命令型の非関数型言語のプログラムがあります。
main:
read contents of abc.txt into mystring
write contents of mystring to def.txt
上記のmain
手順はまさにそれです:一連のアクションを実行する方法を説明する一連のステップ。
これをHaskellのような純粋に関数型の言語と比較してください。関数型言語では、main関数を含め、すべてが式です。したがって、次のように上記のプログラムに相当するものを読み取ることができます。
main = the reading of abc.txt into mystring followed by
the writing of mystring to def.txt
つまり、main
は、評価されると、プログラムを実行するために何をすべきかを説明するアクションを返す式です。このアクションの実際の実行は、プログラマーの世界の外で行われます。そして、これは実際にそれがどのように機能するかです。以下は、コンパイルして実行できる実際のHaskellプログラムです。
main = readFile "abc.txt" >>= \ mystring ->
writeFile "def.txt" mystring
a >>= b
この状況では、「行動a
に続いて行動にa
与えられた結果」を意味すると言うことができ、オペレーターの結果は、行動aとbを組み合わせたものです。b
上記のプログラムはもちろん慣用的なHaskellではありません。次のように書き直すことができます(余分な変数を削除します)。
main = readFile "abc.txt" >>=
writeFile "def.txt"
...または、構文糖衣と表記法を使用します。
main = do
mystring <- readFile "abc.txt"
writeFile "def.txt" mystring
上記のプログラムはすべて同等であるだけでなく、コンパイラーに関する限り同一です。
これは、ファイル、データベースシステム、およびWebサーバーを純粋に機能的なプログラムとして作成する方法です。プログラムにアクション値をスレッド化して結合し、最終的にmain
関数に変換します。これにより、プログラマーはプログラムを非常に細かく制御できます。そのため、純粋に関数型プログラミング言語が状況によっては非常に魅力的です。