Functional composition in Haskell has lower precedence than function application. So add10.mul5 10
is parsed as add10 . (mul5 10)
. Now, the type of .
is given as:
(.) :: (b -> c) -> (a -> b) -> a -> c
The first argument (add10
) has type Int -> Int
, so we can establish that b is Int
, and hence .
expects its second argument to be of type a -> Int
. But instead it's of type Int
. Adding the $
changes the association, and means that instead the function composition is done before applying the composed function to 10.
Everything works in your first example because you're not composing functions, you're just applying them. The equivalent in this case would be trying to do (10+) . 4
, which you will observe also fails.