すごいH本6
アプリカティブファンクター←最初アポクリファと思ってた。
もう今年までに終わる気がしない…
感想
・ファンクターの説明で、文脈を持った値とか足のはえた箱とか、fmapは文脈を持った値を修飾するとか…とにかく混乱した。
・MaybeやI/Oアクションが箱っぽいのはfmapの定義
fmap :: (Functor f) => (a -> b) -> f a -> f b -- f a -> f b -- f ↑ ↑ f -- a -> b
で、fにMaybeやIOが素直に当てはまるように感じた。
・しかしファンクターとしての関数の説明が、定義
instance Functor ((-> r) where fmap f g = (\x -> f (g x)) -- fmap = (.) -- fmap :: (a -> b) -> (-> r) a -> ((-> r) b -- f -- a -> b -- g ↑ ↗ fmap f g = f . g -- r
を見てもしっくりこなかった。
そもそも、ファンクターの定義のfと今回登場したfが同じと勘違いしてたのでかなり時間を食った。アプリカティブのとこで似たような場所に注釈があったけど…
fmapの関係を持ち上げの図式風に書いてみたが、
fmap f g = (\x -> f (g x)) -- fmap :: (a -> b) -> (-> r) a -> ((-> r) b -- f -- ((->) r) a -> ((->) r) b -- g ↑ ↗ fmap f g = f . g -- x
これを、g rを箱gにrが入ったとみるとg(f(r))になってほしいのに、実際はf(g(r))…?
いろいろ悩んだ結果、箱のガワに当たるところを引数を受けるところと考えてみると、少なくともこの章の間はそれで不都合がなかった。いい感じの図式が思いつかなかったのは悔しいけどとりあえず先に進もう。
・↑までのところがすっきりしないままアプリカティブファンクターのとこ読み進めたせいでめちゃくちゃ混乱した。
(+) <$> (+3) <*> (*100) $ 5
の説明が、先に
(+3) <*> (*100) $ 5
を評価してるように最初感じたけど
(+) <$> ((+3) <*> (*100)) $ 5 -- だめ ((+) <$> (+3)) <*> (*100) $ 5 -- おーけー
なので、普通に前から評価してるっぽい。
・その関係でちょっとだけ実験してみた。
fmap (+) (*3) 3 4 -- 13 (+) <$> (*3) 3 4 -- だめ ((+) <$> (*3)) 3 4 -- 13
を見ると、f <$> xとfmap f xは厳密には違うっぽい。
(+) <$> (*3) 3と(+) <$> ((*3) 3 4)の型が一致してたので、ちょっとだけ優先順位が低いのかな。
pure f <*> xは優先順位的にもf <$> xと一致してそう?簡単なのしか見てないのでわからんけど。
・最近MATLABで関数同士を足したいことがあって、ラムダ式でくるめば出来たけどあんまりきれいじゃなかったので、ちょっとこれが使いたくなった(覚えたてのものをなんにでも使いたいタイプ)
・いろいろ考えた末にリストのファンクターがわからなくなった。非決定性計算ってなに?
・箱部分、: []かな…って思いながら
sequenceA [[1,2,3], [4,5,6]] -- [[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]]
を眺めてたら、最初の行の外側の括弧は内側の[a,b]にきてて、2行目の外側の括弧は[1,2,3]と[4,5,6]の:[]がくっついた感じに見えてきた。「残された1,2,3,4,5,6はどうなるの!?」って思ったけど、それがとりあえず全部についてまとめられるから非決定性なのかな。
よくポインタって箱に喩えられてる(批判もみるけどどれが正しいのかは知らない)けど、今回ファンクターが箱に喩えられてたしみんな箱なのかな。