What you want seems to be a composition of binary and unary functions, like this:
compose :: (c -> d) -> (a -> b -> c) -> (a -> b -> d)
compose unary binary a b = unary (binary a b)
And you ask for a point-free version (without mentioning of a
and b
variables). Let's try and eliminate them one by one. We'll start with b
, using the fact that f (g x) = f . g
:
compose unary binary a = unary . binary a
a
is next. Let's desugar the expression first:
compose unary binary a = ((.) unary) (binary a)
And apply the same composition rule again:
compose unary binary = ((.) unary) . binary
This can be further written as:
compose unary = (.) ((.) unary)
Or even as
compose = (.) . (.)
Here, each (.)
'strips' an argument off the binary function and you need two of them because the function is binary. This idiom is very useful when generalised for any functor: fmap . fmap
(note that fmap
is equivalent to .
when function is seen as a functor). This allows you to 'strip' any functor off, for example you can write:
incrementResultsOfEveryFunctionInTwoDimentionalList :: [[String -> Integer]] -> [[String -> Integer]]
incrementResultsOfEveryFunctionInTwoDimentionalList = fmap . fmap . fmap $ (+1)
So, your result becomes:
(fmap . fmap) nub (++)
Edit:
I think I have found the answer my brain was trying to reproduce: Haskell function composition operator of type (c→d) → (a→b→c) → (a→b→d)