I'm often confused by the types of these sorts of function-transforming functions for a minute before I think about them. Another good way of looking at them is to add unnecessary parentheses to their types, and look at them like this:
toFront3 :: (a -> b -> c -> d) -> (b -> c -> a -> d)
That is, toFront3
takes a function of 3 arguments, and gives you a function of the same arguments in a different order.
To have some names:
let g = toFront3 f
g
and f
are both functions of 3 arguments. g
is going to call f
after shuffling its 3rd argument to the front. Therefore the arguments g
will receive are the pre-shuffled arguments. So to go from f :: a -> b -> c -> d
to the type of g
we have to apply the inverse shuffling of arguments that toFront3
does, so that shuffling them will restore the argument order to a -> b -> c -> d
, as is required to be passed to f
post-shuffle.