序文として、あまり書かれていない多くの紹介にもかかわらず、「IO
Monad
」ではありません。それはちょうど "IO
タイプ"です。モナドには魔法はありません。 HaskellのMonad
クラスは、非常に退屈なことです。ほとんどの言語がサポートできるものに慣れておらず、抽象的です。 「IO
IO
Alternative
」とIO
がAlternative
を実装しているにもかかわらず、誰にも呼ばれることはありません。 Monad
に集中することは、学習の仕方に過ぎません。
純粋な言語での効果の原理処理(ではなく、の副作用)の概念的な魔法は、IO
タイプの存在です。それは本当のタイプです。これは "これは不純です"と言っている旗ではありません。これは、Maybe
または[]
のような完全なHaskellタイプの* -> *
です。 IO a -> IO (Maybe a)
のように、IO値を引数として受け入れるタイプのシグネチャは意味があります。ネストされたIOを持つ型シグネチャは、IO (IO a)
のように意味があります。
実際のタイプの場合、具体的な意味を持っている必要があります。タイプとしてMaybe a
はタイプa
の可能性として欠損値を表します。 [a]
は、a
の0以上の値を意味します。 IO a
は、タイプa
の値を生成する一連のエフェクトを意味します。
IO
の目的は、一連の効果を表すことにあります。私が上記のように、彼らは副作用ではありません。彼らはプログラムの害のない葉に隠れることができず、他のコードの背後にあるものを不思議に変えます。代わりに、効果は、それがIO
値であるという事実によってむしろ明示的に呼び出されます。これは人々がIO
タイプを使用してプログラムの部分を最小化しようとする理由です。あなたがそこで行うことが少ないほど、距離を置いてあなたのプログラムを妨害する恐ろしい行動のための方法は少なくなります。
質問の主な推論として、完全なHaskellプログラムは、main
と呼ばれる値IO
と、それが使用する定義のコレクションです。コンパイラは、コードを生成するときに、実質的に一連のエフェクトを実行するコードのハスケルではないブロックを、IO
の値で挿入します。ある意味では、これはサイモン・ペイトン・ジョーンズ(GHCの長年の著者の一人)が彼の話で得ていたものですHaskell is useless。
実際にIOアクションを実行するものは概念的に純粋なままではありません。(そして、Haskell言語内でIO
アクションが実行される非常に不純な関数がありますが、それは外部関数のインタフェースをサポートするために追加されたものではなく、不適切に使用するとプログラムが非常に悪くなります) Haskellのポイントは、エフェクトシステムに原理的なインターフェースを提供し、根本的でないビットを隠すことです。それは実際には実際には非常に便利なやり方です。
(これは私が100%確信しているわけではないのでコメントしています)私の理解は、IOは状態として「現実の世界」を持つ低レベル状態のモナドとしてモデル化されているということです。コンパイラ/ランタイムは実際には、オペレーティングシステムのAPIへのバインディングを使用して実装されたIO操作に変換します。純粋に関数型のプログラミングでは、何かを計算することはできますが、誰にもそれを伝えることはできません。現実の世界でのこれらのステートフルアクションを、基礎となるオペレーティングシステムへの実際の呼び出しに変換できるランタイムが必要です。 – bheklilr
https://wiki.haskell.org/IO_inside#Welcome_to_the_RealWorld.2C_baby –