3分で解るHaskellのArrowの基本メモ
日本語でArrowの説明があまり見付からなかったので、Haskell/Understanding arrows - Wikibooks, open books for an open worldを読んで理解したつもりのメモ。オリジナルの図を見ながらだと分かりやすいかも。誤り・間違いなど、乞うご指摘。
b->cな関数をArrowなるからくり箱に入れると、
(Arrow a) => a b c
こんな型になる。型パラメタが、引数のbと返値のcのふたつ。
- Monadは、値をからくり箱に入れたもの。からくり箱は基本的に(ヘンな)値。
- Arrowは、関数をからくり箱に入れたもの。からくり箱は基本的に(ヘンな)関数。
arr :: (b -> c) -> a b c
- Monadでは、値をからくり箱に入れる関数returnがある。
- Arrowでは、関数をからくり箱に入れる関数arrがある。
(>>>) :: a b c -> a c d -> a b d
- Monadでは、値入りからくり箱を a -> m b な関数を使って繋ぐ (>>=) がある。繋がると全体がまた(ヘンな)値(=からくり箱)
- Arrowでは、関数入りからくり箱同士を繋ぐ (>>>) がある。繋がると全体がまた(ヘンな)関数(=からくり箱)
要は、Arrowは、関数の「入力(引数)を受け取って出力(返値)を出す」という部分を抽象化したもの。
で、(>>>)が関数の合成、つまり(.)にあたる。
f.g
だと、gしてf(評価の遅延とかおいといて)という当たり前のことしか出来ないけど、
(arr g) >>> (arr f)
だと、概念上はgとfを直列に繋ぐという扱いだけど、>>>の実装でいろんなからくりを仕込むことが出来る。(Monadの>>=の実装がいろんなからくりを仕込んでるように)
Arrowは、この直列連結のほかに並列連結がある。すでにからくり箱に入った関数ふたつを並列に繋ぐクラスメソッドがこれ。
(***) :: a b c -> a b' c' -> a (b, b') (c, c')
外部的には、単に引数をタプルで受けて、返値もタプルにしただけ。元ページの図を見ると概念も分かりやすい。
で、Arrowにもdo記法があって、あと、実はMonadもArrow(に出来る)…みたいだけど詳しい事は書いてなかった。
(これらについて、
- 前者については do記法でArrowを使いこなす基本メモ - よくわかりません
- 後者については MonadとArrowの関係。 - よくわかりません
- 実際のプログラミングでの順次/分岐/繰返しについて、ArrowによるHaskellプログラミングの基礎。…パイプ感覚で順次/分岐/繰返し - よくわかりません
に追記)。
追記。最初「(arr f) >>> (arr g)」と書いてたのを「(arr g) >>> (arr f)」に訂正。>>=に使う関数を「a -> m a」と書いてたのを「a -> m b」に訂正。