Reputation: 571
From this answer one learns how to implement the function \x y z -> f x (g y z)
in a pointless way in Haskell, where f
and g
are functions. And my question is
How to write the function
\x -> f (g x) (h x)
in a pointfree manner in Haskell? Heref
g
h
are functions for whichf (g x) (h x)
is defined.
The idea I currently have in mind is something like the following.
uncurry f (mapTuple ($ x) (g, h))
But several tries shows that this is fallacious; even the part map ($ x) [g, h]
is suspicious: what if g
and h
have different ranges?
In addition, readability is not too much an issue here.
Any help is sincerely appreciated.
Upvotes: 1
Views: 628
Reputation: 571
This only serves to collect and put into order the answers in the comments. According to the abstraction-elimination process in the link in the comment by @ PetrPudlák, we can also write
S (S (K f) (S (K g) I)) (S (K h) I),
or, after eta reduction,
S (S (K f) g) h,
where
S x y z = x z (y z)
K x y = x
Specifically in Haskell, thanks to @melpomene for pointing this out, the role of S
is played by ap
, and that of K
by const
. Therefore we can write
ap (ap (const f) g) h
In fact we can further reduce:
ap (const f) g = f . g
So our function can be written as:
ap (f . g) h
If translated to Applicative style, we obtain:
f <$> g <*> h
Then this systematic approach can be applied to all lambda terms, and gives the point-free style. :)
Upvotes: 0
Reputation: 14329
Applicative-style
f <$> g <*> h
join ((g ~> h ~> id) f)
join (f $* g $$ h *$ id)
lurryA @N1 (f <$> (g <$> _1) <*> (h <$> _1))
lurryA @N4 (_1 <*> (_2 <*> _4) <*> (_3 <*> _4)) f g h
Upvotes: 2
Reputation: 120711
The arrow version would be
uncurry f . (g &&& h)
or
(g &&& h) >>> uncurry f
As a diagram:
g ────
╱ ╲
──── &&& >>> uncurry f ───
╲ ╱
h ────
Upvotes: 6
Reputation: 1755
As melpomene suggested, \x -> f (g x) (h x)
is equivalent to liftM2 f g h
.
When you have question concerning how to convert Haskell code into pointfree Haskell code, you can just try Pointfree.io.
It is a great tool which often can tell you when NOT to use pointfree code because it goes completely unreadable sometimes :-)
Upvotes: 4