Pointfree / ((->) r)モナド

http://www.haskell.org/haskellwiki/Pointfree を読んだ。その中で、

> pl \ x -> x * x
join (*)

が何故動くのかで悩んだ。そもそもjoinはMonadに対する関数(join :: (Monad m) => m (m a) -> m a)である。その前には"The @pl (point-less) plugin is rather infamous for using the (-> a) monad to obtain concise code."と書かれており、joinのmが b -> という型(引数型?)、つまり(b -> b -> a) -> (b -> a)だと考えれば話が通りそうである。実際、調べてみると

*Main> :info (->)
data (->) a b 	-- Defined in GHC.Prim
instance Monad ((->) r) -- Defined in Control.Monad.Instances
instance Functor ((->) r) -- Defined in Control.Monad.Instances

となっており、Control.Monad.Instancesでモナドとして定義されていることがわかった。

まずjoinの定義を確認しておく。
http://haskell.org/ghc/docs/latest/html/libraries/base/src/Control-Monad.html#join

join              :: (Monad m) => m (m a) -> m a
join x            =  x >>= id

次に((->) r)モナドの定義を見てみた。
http://haskell.org/ghc/docs/latest/html/libraries/base/src/Control-Monad-Instances.html

instance Monad ((->) r) where
        return = const
        f >>= k = \ r -> k (f r) r

なるほど、fに引数rを与えて評価した結果がkに渡されて、加えてkにもr自体が渡されている。returnがconstなのも興味深い。引き回されているrが引数として渡されるのだから、これを読み捨ててしまえばいいわけだ。

最後にjoin (*) xを簡約してみれば、確かにx * xになっていることが確認できた。

((*) >>= id) x
(\ r -> id ((*) r) r) x
((*) x) x
x * x