関数合成演算子(.)
は、次のように定義され(.)
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(.) f g x = f (g x) -- or, equivalently,
(.) f g = \x -> f (g x)
(.) f = \g -> \x -> f (g x)
(.) = \f -> \g -> \x -> f (g x)
(.) = \f -> (\g -> (\x -> f (g x) ) )
タイプ(b -> c) -> (a -> b) -> (a -> c)
は(b -> c) -> (a -> b) -> a -> c
と書くことができる。 ->
型シグネチャでは、左に関連付けられている関数アプリケーションに対応する右に「関連付け」、
f g x y z ... == (((f g) x) y) z ...
したがって、「データフロー」は右から左にありますx
はg
、その結果はf
になり、最終結果が生成されます。
(.) f g x = r
where r = f (g x)
-- g :: a -> b
-- f :: b -> c
-- x :: a
-- r :: c
(.) f g = q
where q = \x -> f (g x)
-- g :: a -> b
-- f :: b -> c
-- q :: a -> c
....
構文上、以下はすべて同じです:
(.) f g x = (f . g) x = (f .) g x = (. g) f x
これは「 演算子セクションの 3つのルール」として把握するのが簡単です 。「欠落している引数」が演算子の近くの空のスロットに入るだけです。
(.) f g = (f . g) = (f .) g = (. g) f
-- 1 2 3
方程式の両辺に存在するx
は省略することができる。これはエタ収縮として知られている。したがって、関数の構成の定義を書き留める簡単な方法は、
(f . g) x = f (g x)
これはもちろん「引数」 x
指します。 x
なくても(f . g)
書くときはいつでもポイントフリーのスタイルとして知られています。