I have been wondering how different standard Haskell functions could be implemented point-free. Currently, I am interested in uncurry
and I feel this one is quite non-trivial.
The main problem is that we are unable (or as it seems to me) to group the arguments. If we had uncurry
(in fact, uncurry ($)
would suffice) in use, the solution would have been quite simple:
- Make a tuple
(f, (x, y))
. - Apply
assoc1 :: (a, (b, c)) -> ((a, b), c)
to the tuple and get((f, x), y)
. - Apply the uncurried
($)
to the first element of the pair and get(f x, y)
. - Apply the uncurried
($)
to the pair itself and getf x y
.
Without the uncurried ($)
we would have to extract both elements of the pair separately. E.g.:
uncurry f pair = f (fst pair) (snd pair)
I do not reckon this to be a smooth way to implement something point-free.
In fact, we have got this uncurried ($)
at our behest: Control.Arrow.apply
(other useful for the solution combinators could also be imported from Control.Arrow
). Therefore:
import Control.Arrow ((>>>), (&&&), first, app)
myUncurry = let myAssoc1 = (fst &&& (fst . snd)) &&& (snd . snd)
in (,) >>> (>>> myAssoc1 >>> first app >>> app)
Yet, this feels a small bit like cheating.
Are there any other approaches towards this problem which do not require anything like app
?