Solution (source code)

= Solution

Application binds more tightly than <function composition>, and `(.)` associates to the right. Let

``
g :: a -> b -> c
``

Then `y :: a` and `g y :: b -> c`. To compose to its left, `h x` must have type `c -> a`, so `x :: d` and `h :: d -> c -> a`. The outer occurrence of `g` receives that `a`, producing a function of type `b -> c`. Consequently `g . h x . g y` has type `b -> b -> c`, and the <principal type> is \b[`f :: (a -> b -> c) -> (d -> c -> a) -> d -> a -> b -> b -> c`]. No <Haskell type class> constraint is introduced.