I'm trying to figure out the point free form of f x y = 3 + y/x
in Haskell. I thought it would be f = (3.0+) . flip (/)
, but the answer is f2 = curry $ (3.0+) . (uncurry $ flip (/))
, which is the same as f1 = curry ((3.0+) . (uncurry (flip (/))))
, e.g. the answer I got but with uncurry before flip and curry at the beginning.
I see how that version works, but I'm not sure why the curry and uncurry functions are needed, and why my version doesn't work? The type of (3.0+)
is a -> a
, which I thought would work if you fed that function with the result form flip (/)
via function composition, but (3.0+) . flip (/) 2 10
results in an error (why?) and does not yield 8. Isn't it redundant to uncurry and then curry again?
The type signature of the .
is (.) :: (b -> c) -> (a -> b) -> a -> c
. As you can see, this only works if the second function (in your answer flip (/)
) has one argument. In case it has two arguments, we can use the "owl operator" (.) . (.)
, which has type:
(.) . (.) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c
Or we can use currying. By using uncurry :: (a -> b -> c) -> (a, b) -> c
on the flip (/)
part, we construct a function:
uncurry (flip (/)) :: Fractional c => (c, c) -> c
so now we work with a single tuple (thus one argument), and then we use curry :: ((a, b) -> c) -> a -> b -> c
to "unpack" the resulting first argument tuple again.
As discussed before, we can use the owl operator:
((.) . (.)) (3.0+) (flip (/))
-- ^ owl ^
Or we can use a syntactically more complex version of the owl operator:
((3 +) .) . flip (/)