Control.Arrow.app

Control.Arrow - mzsmsの雑記を読んで Arrow というものを理解しようとしてたんだけど、app 関数でちょっとつまずいたのでメモしておく。
loop はあんまりにも分からなかったので後回し。なんとなくフリップフロップ回路に似ている気はした。

型で考えてから図にしてみる

悩んでたコードは先のブログのこのコード。

ghci> let g = id *** (*2) >>> app
ghci> g ((+10), 2)

app の型と、関数インスタンスに限定したときの型と値は、

app :: ArrowApply a => a (a b c, b) c
app :: (a -> b, a) -> b
app (f, a) = f a

id *** (*2) の型は、

id *** (*2) :: Num a => (b, a) -> (b, a)

>>> は、

(>>>) :: (a -> b) -> (b -> c) -> a -> c
(>>>) = flip (.)

よって id *** (*2) >>> app の型は、

id *** (*2) ::         Num a => (b,      a) -> (b,      a)
app ::                                         (a -> b, a) -> b
id *** (*2) >>> app :: Num a => (a -> b, a) -> b

破線矢印を関数適用、実線矢印がその結果として図で書くと計算はこんな感じ。

分かると

分かると大したことないな、という感じ。