IOモナド
IOモナドは副作用を扱い、その副作用がIOモナドの外にもれないように、一度IOモナドの中にいれた値は原則として取り出すことはできない
「副作用を伴う」という文脈を扱う
PureScriptでは、「Effectモナド」と言う(たぶん)
型のイメージ
code:hs
type IO a = World -> (a, World)
これはあくまでもイメージ
内部実装は処理系の裏側に隠されている
Stateモナドと同じ様に考えられる
実装
code:hs
instance Monad IO where
m >> k = m >>= \ _ -> k
return = returnIO
(>>=) = bindIO
fail s = failIO s
架空の定義 ref
code:hs
newtype IO a = IO (RealWorld -> (RealWorld, a))
instance Monad IO where
return a = IO $ \w -> (w, a)
(IO h) >>= f = IO $ \w ->
let (nw, a) = h w
(IO g) = f a
in g nw
関連する関数
putStrLn :: String -> IO ()
引数の文字列を画面に出力し、改行する
putStr
引数の文字列を画面に出力し、改行しない
putChar
引数の文字を画面に出力する
print :: Show a => a -> IO ()
引数の値を文字列化し、画面に出力する
putStrLn . showと同じ
getLine :: IO String
入力を一行読み込む
code:hs
name <- getLine -- 一行読んで変数nameに束縛
IOモナド変換子は定義できない?
HaskellのIO操作の実行は他の関数やモナドに勝手に入れ子にしてはならず、IOモナドでのみ可能になっているからです。 ref
参考
すごいH本 8章
Haskell IOモナド 超入門 - Qiita
https://discuss.ocaml.org/t/io-monad-for-ocaml/4618/11
https://qtamaki.hatenablog.com/entry/20120114/1326507956
https://mizunashi-mana.github.io/blog/posts/2019/05/ghc-io-inside/
https://ubiteku.oinker.me/2017/05/08/purpose-of-functional-programming/
命令をデータとして表現する
https://github.com/kowainik/eio
EIO
なに?
https://kazu-yamamoto.hatenablog.jp/entry/20131225/1387938629
https://wiki.haskell.org/IO_inside
IO野中を覗く
https://haskell.jp/blog/posts/2020/io-monad-and-sideeffect.html