I have to convert a Haskell type signature into a term. The type signature is :
f :: (a -> b -> c) -> (d -> b) -> (d -> a) -> d -> c
The correct resulting term is :
f g h j x = g (j x) (h x)
and here lies my problem as I understand it g is a function which returns a function which returns c and c is function which returns a function d which returns b and b is a function which returns itself which then returns itself again which then returns c.
Correct me if i am wrong.
What I don't get is why is g taking (j x) as first argument and (h x) as second argument. Shouldn't it be the other way around? Haskell is right associative and h is the secound parameter given to the function f and not j.
g :: a -> b -> c,h :: d -> b,j :: d -> a, andx :: dare all independent arguments tof; their order implies nothing about how we might end up using them in the definition off.To start, we know that
fuses its arguments to return a value of typec. But none of the arguments have a value of typec; the only way to get a value of typecis to useg. But in order to useg, you need arguments of typeaand typeb, and none off's arguments have those types. But we could usehandjto get them, if we had an argument of typedto apply them to, and lo and behold, we do have a value of typed: the argumentx!.which can be flattened to the original answer of
If you want to think of the return value of
fas beingd -> c, rather than justc, you can eliminatexfrom the definition with some point-free trickery.You can even go a little further to remove
handjas arguments, but the result, though simple, is even more incomprehensible:Moral of the story: sometimes point-free style abstracts away distracting details, other times it completely obscures the meaning of the function.