すごいHaskellを読んでみて、結局理解があやふやなままなのがタイトルの2つ(というか似たようなもんなので実際は一つかな)だ。使い方はわかるけどなんでそうなんのかなー的なモヤモヤ感が残りまくりだ。
定義(p.247)だと
pure x = (\_ -> x) f <*> g =\x -> f x (g x)
ってなってて、pureはいいんだけど、なんでfは二引数取るようになってんだよと(Readerモナドも一緒)。 本書の例のとおりに
(+) <$> (+3) <*> (*100)
を考えた場合
Prelude Control.Applicative> :t ((+3) <*> (*100)) <interactive>:1:12: Occurs check: cannot construct the infinite type: a0 = a0 -> b0 Expected type: (a0 -> b0) -> a0 Actual type: (a0 -> b0) -> a0 -> b0 In the second argument of `(<*>)', namely `(* 100)' In the expression: ((+ 3) <*> (* 100))
は、普通にエラー。まぁ実際そうだし、fってこれだよなぁ
Prelude Control.Applicative> :t ((+) <$> (+3)) ((+) <$> (+3)) :: Num a => a -> a -> a
p.249の例を見るとつないでるっていうよりは分配してる感しか得られないんだよなぁ。
Prelude Control.Applicative> (\x y z -> [x,y,z]) <$> (+3) <*> (*2) <*> (/2) $ 5 [8.0,10.0,2.5]
120616 追記
bind(>>=)ってIOが強く印象づけられてたのでb順番に計算を実行するための枠組みだと思っていたが、別に計算を連鎖させるわけじゃないのかな。
より大きい計算を作るための計算戦略の枠組みを提供するだけで。