Usefulness of "function arrows associate to the right"?

Function arrows associate to the right but [...] what is usefulness of this information?

If you see a type signature like, for example, f : String -> Int -> Bool you need to know the associativity of the function arrow to understand what the type of f really is:

  1. if the arrow associates to the left, then the type means (String -> Int) -> Bool, that is, f takes a function as argument and returns a boolean.
  2. if the arrow associates to the right, then the type means String -> (Int -> Bool), that is, f takes a string as argument and returns a function.

That's a big difference, and if you want to use f, you need to know which one it is. Since the function arrow associates to the right, you know that it has to be the second option: f takes a string and returns a function.

Function arrows associate to the right [...] function application associates to the left

These two choices work well together. For example, we can call the f from above as f "answer" 42 which really means (f "answer") 42. So we are passing the string "answer" to f which returns a function. And then we're passing the number 42 to that function, which returns a boolean. In effect, we're almost using f as a function with two arguments.

This is the standard way of writing functions with two (or more) arguments in Haskell, so it is a very common use case. Because of the associativity of function application and of the function arrow, we can write this common use case without parentheses.


When defining a two-argument curried function, we usually write something like this:

f :: a -> b -> c
f x y = ...

If the arrow did not associate to the right, the above type would instead have to be spelled out as a -> (b -> c). So the usefulness of ->'s associativity is that it saves us from writing too many parentheses when declaring function types.

Tags:

Haskell