($) と (.)

($) と (.) のことをよくわかっていないので調べる。

ghci で見てみる。

Prelude> :i ($)
($) :: (a -> b) -> a -> b   -- Defined in `GHC.Base'
infixr 0 $

Prelude> :i (.)
(.) :: (b -> c) -> (a -> b) -> a -> c   -- Defined in `GHC.Base'
infixr 9 .

($)は引数に関数をひとつ取るが、(.) は二つ取る。関数合成だから当然か。 結合の優先順位は ($) は一番弱く、 (.) が一番強い。

実装はどうなっているかというと、base/GHC/Base.lhs を見てみる。

($)   :: (a -> b) -> a -> b
f $ x =  f x

(.)    :: (b -> c) -> (a -> b) -> a -> c
(.) f g = \x -> f (g x)

($) は、一見意味ないんじゃないかと思うけど、結合性を右結合にするところに意味があるのか?右結合にすることによって、カッコを省略できる、と。

(.) f g がとる引数はひとつだけ。\x y -> f (g x y) のようにできるとよく勘違いしてしまう。

参考