Haskell Language
機能構成
サーチ…
備考
関数合成演算子(.)
は、次のように定義され(.)
(.) :: (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)
書くときはいつでもポイントフリーのスタイルとして知られています。
右から左への合成
(.)
2つの関数を作成し、一方の出力を他方の入力に渡すことができます:
(f . g) x = f (g x)
たとえば、入力番号の後続を二乗する場合は、次のように書くことができます。
((^2) . succ) 1 -- 4
(.)
へのエイリアスである(<<<)
もあります。そう、
(+ 1) <<< sqrt $ 25 -- 6
左から右の構図
Control.Category
は、 (>>>)
定義します。これは、関数に特化している場合、
-- (>>>) :: Category cat => cat a b -> cat b c -> cat a c
-- (>>>) :: (->) a b -> (->) b c -> (->) a c
-- (>>>) :: (a -> b) -> (b -> c) -> (a -> c)
( f >>> g ) x = g (f x)
例:
sqrt >>> (+ 1) $ 25 -- 6.0
バイナリ関数による合成
正規の構成は、単項関数のために機能します。バイナリの場合、
(f .: g) x y = f (g x y) -- which is also
= f ((g x) y)
= (f . g x) y -- by definition of (.)
= (f .) (g x) y
= ((f .) . g) x y
したがって、η - 収縮による(f .: g) = ((f .) . g)
、さらには、
(.:) f g = ((f .) . g)
= (.) (f .) g
= (.) ((.) f) g
= ((.) . (.)) f g
そう(.:) = ((.) . (.))
、半有名な定義。
例:
(map (+1) .: filter) even [1..5] -- [3,5]
(length .: filter) even [1..5] -- 2
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow