すごいHaskellたのしく学ぼう!(略してすごいH本)ですが、難しかったけどなんとか読了できました。
しかしこの本、全体的に解説が丁寧なのですが、重要じゃないとみなされた部分の説明は、意外とザックリしてる印象です。
というわけで、ちょっと理解に時間がかかった箇所を自分なりにまとめておこう! という記事です。
最初に躓いた箇所は、第11章の249P「関数もアプリカティブだよ」というところでした。
結論は
<*> :: f g = \r -> (f r) (g r)
なのですが、最初に見たときはサッパリだったので、これについてメモします。
アプリカティブファンクターの<*>の定義は
<*> :: f (a -> b) -> f a -> f b
だから、この f を関数の型クラス ((->) r)に置き換えて
<*> :: (r -> (a -> b)) -> (r -> a) -> (r -> b) =============== ======== f g
上の fと gから (r -> b) なる関数を返すように<*>を定義できたらOKなのでそのつもりで眺めると
- f r は (a -> b)
- g r は a
だから、
(f r) に (g r) を食わせると b が返ってくることがわかる。
で、f <*> g が返したいのは r を受け取り b を返す「関数」なので、r をラムダ式の引数に抜き出して
f <*> g = \r -> (f r) (g r)
となる。
関数を文脈としてキープする、という意味は、「同じ型の r を受け取る関数であり続ける」という意味であることに注意、というわけですね。