Haskellの関数合成
-
16-09-2019 - |
質問
私はHaskellの上でこののチュートリアルrel="noreferrer">のの関数合成の次のように:
(.) :: (b->c) -> (a->b) -> (a->c)
f . g = \ x -> f (g x)
何の例は、私がここで定義されているもののように私を啓発するだろうと信じている、提供されませんでした。
誰かが機能組成物が使用されている方法の(解説付き)簡単な例を提供することができますか?
解決
関数組成物は、単一関数に2つの機能を「構成」する方法です。ここでは例があります:
あなたは、これらの機能を持っていると言います
even :: Int -> Bool
not :: Bool -> Bool
、あなたは上記の2を使用して、独自のmyOdd :: Int -> Bool
関数を定義します。
これを行うための明白な方法は以下の通りです。
myOdd :: Int -> Bool
myOdd x = not (even x)
しかし、これは、関数合成を使用して、より簡潔に行うことができます:
myOdd :: Int -> Bool
myOdd = not . even
myOdd
機能は、まったく同じように動作しますが、二番目のは、一緒に「のり-INGの」二つの機能によって作成されます。
これは特に便利ですシナリオは、明示的なラムダの必要性を除去することです。例えばます:
map (\x -> not (even x)) [1..9]
に書き換えることができます:
map (not . even) [1..9]
エラーのビット短く、小さい部屋ます。
他のヒント
楽しいサイドノート。関数合成は、ロジックで三段論法のと同等です。
すべての人が死ぬべきです。ソクラテスは人間です。したがって、ソクラテスは致命的である。
三段論法1つに2つの材料含意を構成する
(Man => Mortal), (Socrates => Man), therefore (Socrates => Mortal)
そこで...
(b -> c) -> (a -> b) -> (a -> c)
... .
関数の型です。
組成物 f
とg
の最初g
によって返される値にf
次いで、その引数にg
を適用する機能です。その後f
の戻り値を返します。
このアイデンティティは啓発かもしれます:
f (g x) = (f . g) x
は、Java / Cのバックグラウンドを持っている場合は、この例を考えてみます:
int f(int x);
int g(int x);
int theComposition(int x) { return f(g(x)); }
この例では不自然ですが、私たちは持っていると仮定します。
sqr x = x * x
inc x = x + 1
私たちは、x ^ 2 + 1を計算する関数を書きたいです。私たちは書くことができます。
xSquaredPlusOne = inc . sqr
(意味している
xSquaredPlusOne x = (inc . sqr) x
を意味する
xSquaredPlusOne x = inc(sqr x)
F = INCので、G = SQR)。
関数組成物は、2つの以上の機能一緒に鎖の方法です。多くの場合、配管をシェルになぞらえています。例えば、Unixスタイルのシェルで、次のようなものを書くかもしれません。
cat foo.txt | sort -n | less
これは、cat
を実行sort
に出力を供給し、そしてそれからless
に出力を供給します。
厳密には、これはHaskellの$
演算子のようなものです。あなたが好きなものを書くかもしれません。
sum $ sort $ filter (> 0) $ my_list
シェル例とは異なり、これは右から左に読み、ことに注意してください。だから我々は、入力としてmy_list
で開始し、その後、私たちはそれをfilter
そして、その上にsort
を実行し、我々はそれのsum
を計算します。
関数合成演算子、.
は、類似した何かを。上記の例は番号を生成します。以下の例では、の機能を生成の
sum . sort . filter (> 0)
私たちは実際にこのリストにはフィードしていないことに注意してください。代わりに、私たちは新しい関数を作成した、と私たちはその機能に、いくつかの異なるリストを養うことができます。たとえば、あなたがこの機能に名前を付けます。
my_function = sum . sort . filter (> 0)
それとも、別の関数の引数として渡します。
map (sum . sort . filter (> 0)) my_lists
あなたは基本的にあなたが機能の他の並べ替えを使用することができる場所であればどこでもそれを使用することができます。それは「私が一緒にチェーンにこれらの機能をしたい」というのは、単に迅速かつ読みやすい方法です。
desort = (reverse . sort)
今desort
は逆に、リストをソートする機能です。基本的には、desort
は、リターンのことをsort
にそれの引数を供給し、その後、sort
にreverse
からの戻り値を供給します。だから、それをソートし、それがソートされたリストを反転させます。