Chain multi-parameter functions

Suppose I have two functions: f:X->Y and g:Y*Y->Z I want to make a third function, h(a, b) = g(f(a), f(b)) .

 hab = g (fa) (fb) 

Is there any way to write it as h(a, b) = g*f (a, b) ?

But what if h(a,b,c,d) = g2*g1*f2*f1 (a,b,c,d) , where g_i takes 2 arguments?

+6
source share
3 answers

A Google search for functions with the correct signature shows on from Data.Function. According to his documentation,

 g `on` f 

It looks like you want.

+10
source

The on combinator (in Data.Function , as indicated by gspr in another answer) is defined

 g `on` f = \xy -> g (fx) (fy) 

What would you write

 h = g `on` f 

You can make generalizations of this, for example

 g `on3` f = \xyz -> g (fx) (fy) (fz) g `on4` f = \wxyz -> g (fw) (fx) (fy) (fz) 

So you can write

 h = g `on3` f 

There may be a way to write on3 and on4 in terms of on , but if there is, I cannot see it at the moment.

+7
source

You can also find interesting arrows. Here is one way to do this:

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

Which is equivalent to your example (except that g and f are not free) and on . Using:

  • *** definition for functions:

     (***) fg ~(x,y) = (fx, gy) 
  • uncurry definition :

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

And substituting them in the original equation:

  • hgfab = uncurry g (fa, fb) (definition used *** )

  • hgfab = g (fa) (fb) ( uncurry definition is uncurry )

+6
source

All Articles