雑記帳

アマチュア視点から思う Haskell の魅力

(先日友人にかましてしまったやつのロングバージョン。)
アマチュア視点から思う Haskell の魅力
(Haskell 記事用画像)
Haskell をやっておくと、他の言語の理解がより捗る
(..)
綺麗な数学理論が背景にあるのでわかりやすい!
(..)
型付けが非常に厳しいにも関わらず、強力な型推論機能のおかげで明示的な型の指定が大方省ける!
(..)
モナド構造として公理的に提供されている IO アクション組み立て周辺の機構がかなり優秀!
(..)
状態トランスフォーマが状態へ作用する際に生成することになる値が作用する状態に依らないことの機械的な判定と、その場合の値の取得が安全にできるようになっている
純粋関数型言語ということで、通常の命令型言語では当たり前にできるような「変数の書き換え」はできない。
「書き換え可能なブロックを作って、そのブロック内のデータを取得したり書き換えたりする IO アクション」はあっても、そのようなことを Haskell で直接的に記述することはできない。
また「IO アクション (特別な種類の状態トランスフォーマ) を実世界で動作させて最終出力として得られることになる値」は「状態トランスフォーマが作用する実行時の実世界の状態」に依存し、Haskell プログラムのコーディングの段階においては、実行の瞬間に作用される世界の状態を把握していない (状態が既知の量として手元にない) 以上、その最終出力を一般に知ることはできない。
大まかに、Haskell プログラムが呼び出されると、呼び出された瞬間の実世界の状態に対して、main というラベルが付けられた状態トランスフォーマを作用させるといった感じの約束になっているが、一方で Haskell コード内で IO アクションの実行ができるわけではない。
純粋関数型言語である Haskell それ自体ができることは「IO アクションの組み立て」までであり、その先の話までは知り得ない。
とはいえそうなると、参照型やポインタ型の値を使用する処理の完成形は必ず全て一つの IO アクションとして与える羽目になり、
「最終出力に不確定要素はないような処理について、パフォーマンス向上のために参照型を使いたいけど、IO アクションとして組み立てる羽目になるのはうれしくない。」
という問題の解決策として、「ST モナド」が提供されている。
これは「状態への作用時に発生する値が作用する状態に依らない (最終出力が不確定要素を伴わない) 状態トランスフォーマ」を「その作用する状態によらず得ることのできる最終出力」に置き換える術を与える。
(同じことを unsafe 関数でもできることはできるが、ST では「最終出力が作用する状態に依存する状態トランスフォーマから、作用する状態によらず得ることのできる最終出力をはじき出す」といった矛盾した意味のない操作は技術的にできなくなるし、そもそも unsafe 関数は基本的に使用が奨励されていない危険な黒魔術なのでアマチュアが使用するべきではない。)
モナド構造が与える糖衣構文である do 記法のおかげで、関数型とは思えない程見通しの良いコーディングができる!
(..)
自然数対象を持つカルテシアン閉圏で一般的に行える変数フリーな射の構成を適用できる!
正攻法で考えていると思いつきづらい (自然数対象 を持つカルテシアン閉圏で可能な) 一般的抽象的な射の構成法というのを Haskell でダイレクトに実践することができる。
トポスではないため、ETCS で行えるような「自然数同士の間の順序の構成」のようなことまではできないが、「自然数同士の間の加法・乗法、階乗、冪乗、テトレーション」などなどは一般論での構成法になぞって考えることで、それぞれ実際に動作する変数フリーな関数として得ることができる。(何が面白いのかといえば、そうやって構成される関数は、一見するとめちゃくちゃなギャグコードなのに、しっかりと一般論で提示されている通りの動作してくれるという点。)
具体的にどんな感じなのかは「Haskell 言語を使った階乗関数の様々な実装例 (Wikipedia の例だけでは物足りない方向け)」という記事内で紹介している最後の例を参考にしてほしい。