アクション
割と雑に使っている..mrsekut.icon
IOに関係ないときも「アクション」と呼んだりしている
基本的な型を包み込んでいるモナドの値
あれ、やっぱ「アクション」ってIOだけのものだったりするの?
IO aのみのことをアクションって呼ぶの?
アクションは純粋ではない
例えばgetLineは毎回異なる値を返す
アクションの中でしか、他のアクションから値を取り出せない
つまりdoの中でしか。
副作用を扱うようなもののことを関数と区別してアクションと呼ぶ
結果が変化する可能性があるものなど
乱数
時刻取得
ファイル入出力
画面への描画
do式全体もアクションになる
HaskellはmainというIOアクションしか実行できない
だからいつもmain = doって書いてる
main :: IO ()
アクションを返す関数
putStrLn :: Steing -> IO ()はアクションではない
actionを作る関数である
IO ()がアクション
code:haskell
promptLine :: String -> IO String
promptLine prompt = do
putStr prompt
getLine
副作用
乱数など、状態を持ち合わせ毎回異なる値を返す関数は定義できない
アクションから値を取り出す方法
<-を使う
doの中でしか使えない
code:hs
main = do
r <- hogeAction -- actionから値を取り出して、rに束縛
print r -- その後、rを出力
=<<を使う
一時変数を経由せずにアクションから値を取り出して関数に適用させる
「アクション」と「アクションを返す関数」を結びつける
code:hs
main = do
print <- hogeAction -- エラー
print =<< hogeAction
>>=
bindと呼ぶ
逆向き
「アクション」と「アクションを返す関数」を結びつける
code:hs
main = do
hogeAction >>= print
以下の3つはすべて同じ
code:hs
main = do
-- 一度変数を経由する
r <- hogeAction
print r
-- =<<を使う
print =<< hogeAction
-- bindを使う
hogeAction >>= print
mainは「アクションが束縛された変数」である
>=>
actionを返す関数を合成
<=<
unit ()
空のタプルのことを「unit」と呼ぶ
(): unit
アクションの種類
IO
IO Int(数値が取り出せるアクション), IO Charなどの型がある
code:hs
-- 数値が取り出せるIO Int型を返す関数
dice :: IO Int
dice = getStdRandom $ randomR (1,6)
main = do
print =<< dice
アクションを返す関数
return
code:shell
Prelude> :t return
return :: Monad m => a -> m a
print
IOモナドを返す
文字が表示されるのは、関数が呼ばれるタイミングではない
関数が返したアクションから値を取り出すタイミングの副作用
code:hs
print -- 関数
print "abc" -- 関数を呼んで、戻り値がアクション
code:shell
Prelude> :t print
print :: Show a => a -> IO ()
参考