こうもりがっぱ

日々のダストボックス

なぜ Haskell の (IO a) は IO でパターンマッチできないのか

なんてことを思ったわけです。
ちょっと考えるとただの勘違いなので恥ずかしいです。

まず IO a はそういう型名なのであって IO a という型コンストラクタではないということです。
IO の型定義は http://www.haskell.org/ghc/docs/latest/html/libraries/ghc-prim-0.2.0.0/src/GHC-Types.html#IO に書いてありますが、ここを見るとわかるように

newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))

となっている訳ですね。
これは State モナドの定義となっていて、誤解を恐れずに言うと

IO 操作というのは、世界を引数にとって IO 操作後の世界と何かの値を返す関数

となっているわけです。
なのでそもそも (IO a) という型は a という値そのものをバインドしているのではなく、
世界に干渉して a を持ってきてくれる関数な訳ですね。

なので IO は単純なパターンマッチでは剥がすことはできません。