IOはアプリカティブファンクター
IO は Applicative
instance Applicative IO where pure = return a <*> b = do f <- a x <- b return (f x)
return
は何もしない I/Oアクションを返す。
IOに関する <*>
演算子は、
2つのI/O アクションを1つに糊付けするにあたって逐次実行という意味が加わっている。
myAction :: IO String myAction = do a <- getLine b <- getLine return $ a ++ b
これをアプリカティブスタイルで書ける。
myAction :: IO String myAction = (++) <$> getLine <*> getLine
getLine は実世界から文字列をとってきてくれる小さな箱。
(++) <$> getLine <*> getLine
は、
小さな箱を2つ実世界に送り出して端末から入力行を取得し、
結合して返してくれる大きな箱が作られる。
つまり、式 (++) <$> getLine <*> getLine
は I/O アクションである。
よって、このように書くことができる。
main = do a <- (++) <$> getLine <*> getLine putStrLn $ "The two lines concatenated turn out to be: " ++ a
関数もアプリカティブファンクター
関数 (->) r
instance Applicative ((->) r) where pure x = (\_ -> x) f <*> g = \x -> f x (g x)
pure
は、引数を無視して常にその値を返す関数
を作る。
*Main> :t (+) <$> (+3) <*> (*100) (+) <$> (+3) <*> (*100) :: Num b => b -> b *Main> (+) <$> (+3) <*> (*100) $ 5 508
引数を (+3)
と (*100)
に渡し、+
を使う関数ができる。
所感
関数のアプリカティブファンクターの処理順が、<*>
、<$>
の順番になるのは何故なんだろうか。

- 作者: MiranLipovaca
- 出版社/メーカー: オーム社
- 発売日: 2017/07/14
- メディア: Kindle版
- 購入: 4人 クリック: 9回
- この商品を含むブログを見る