2013-02-18 14 views
6

私は、2つの関数、f:X->Yg:Y*Y->Zがあるとします。 私は第3の機能を作りたい、h(a, b) = g(f(a), f(b))マルチパラメータ関数の連鎖

h a b = g (f a) (f b) 

h(a, b) = g*f (a, b)ようにそれを書くための方法はありますか?

h(a,b,c,d) = g2*g1*f2*f1 (a,b,c,d)の場合は、g_iは2つの引数をとりますか?

+0

あなたの2つの例では、同期していません。最初は 'g(f1a)(f2b)'または2番目の 'g(fa)(fb)(fc)(fd)'でなければなりません。 –

+0

'h = \ a b - > g(f a)(f b)'は 'h =(。f)と書くことができます。 g。 f'ですが、読みやすくするべきではありません。 –

+0

新しい2番目の例では、 'f'は' arg 'を取る関数を意味し、 'g'は2を取る関数です。次に、第3レベルが必要です。あなたは完全にそれを完全に書くことができますか? –

答えて

10

right signatureを持つ関数のHoogleを検索すると、Data.Functionからonが得られます。そのドキュメントによれば、

g `on` f 

が好きなようです。 (別の答えにgsprで指摘したようにData.Functionで、)onコンビネータが

あなたは

h = g `on` f 

を書き込むことができるようになる

g `on` f = \x y -> g (f x) (f y) 

によって定義され

7

あなたは、より高い次元の一般化を行うことができます例えば、

g `on3` f = \x y z -> g (f x) (f y) (f z) 

g `on4` f = \w x y z -> g (f w) (f x) (f y) (f z) 

あなたが書くことができるように

h = g `on3` f 

onの面でon3on4を書くための方法があるかもしれませんが、そこにある場合、私は、現時点ではそれを見ることができません。

6

また、興味深い矢印があります。あなたの一例に相当し

h g f a b = uncurry g ((f *** f) (a, b)) 

(ことを除いてgfは無料ではありません)とon:ここでは1つの、それを行う方法です。使用:機能のための***

  • definitionを:uncurry

    (***) f g ~(x,y) = (f x, g y) 
    
  • definition

    uncurry f p = f (fst p) (snd p) 
    

そして、元の方程式にそれらを代入:

  1. h g f a b = uncurry g (f a, f b)(使用***定義)

  2. h g f a b = g (f a) (f b)uncurry定義を使用)