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))
.
h a b = g (f a) (f b)
Is there any way to write it like h(a, b) = g*f (a, b)
?
And what if h(a,b,c,d) = g2*g1*f2*f1 (a,b,c,d)
, where g_i
takes 2 args?
Searching Hoogle for functions with the right signature reveals on
from Data.Function. According to its documentation,
g `on` f
seems to be what you want.
The on
combinator (in Data.Function
, as pointed out by gspr in another answer) is defined by
g `on` f = \x y -> g (f x) (f y)
Which would allow you to write
h = g `on` f
You can make higher-dimensional generalizations of this, for example
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)
So that you could write
h = g `on3` f
There may be a way to write on3
and on4
in terms of on
, but if there is I can't see it at the moment.
You may also find Arrows interesting. Here's one way to do it:
h g f a b = uncurry g ((f *** f) (a, b))
Which is equivalent to your example (except that g
and f
are not free) and on
. Using:
definition of ***
for functions:
(***) f g ~(x,y) = (f x, g y)
definition of uncurry
:
uncurry f p = f (fst p) (snd p)
And substituting them into the original equation:
h g f a b = uncurry g (f a, f b)
(used ***
definition)
h g f a b = g (f a) (f b)
(used uncurry
definition)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With