"Programming with Arrows" http://www.cs.chalmers.se/~rjmh/afp-arrows.pdf
の昨日の続き。

1.2 The Arrow class

関数の結合と、Kleisli Arrows の結合、両方ができたので、
Arrow をclassにして、統合しようと。そのために、type Kleisli を
newtypeで定義しなおす、と。

class Arrow ar where
    arr ::(a -> b)-> ar a b
    (>>>)::ar a b -> ar b c -> ar a c

newtype Kleisli m a b = Kleisli {runKleisli :: a-> m b}

instance Monad m => Arrow (Kleisli m )where
    Kleisli f >>> Kleisli g = Kleisli (\b -> f b >>= g)
    arr f = Kleisli $return . f

count = Kleisli readFile >>> arr words >>> arr length >>> Kleisli print
main = runKleisli count "test.txt"

関数も。関数をinstanceにするにはいったいどう書くのかと思ったら、
関数の型コンストラクタは、(->)だからinstance Arrow (->) where と書けば良いらしい。
なるほど。

instance Arrow (->) where
    arr = id
    (>>>) = flip (.)

f x = x * 2
g x = x + 1

h = f >>> g
main = print $ h 2

これで何が嬉しいのかは、まだまったく分かりません。