Reputation: 127
I'm trying to wrap my head around the return type of the function foo
below. foo
returns a lambda function which takes a function f
of type int -> int
and an int
y
and evaluates to an int
.
How come then that the type isn't
int -> int -> int -> int
?
Writing the return type of foo
as any other than (int -> int) -> (int -> int)
, Visual Studio complains.
let next (x:int) = x + 1
let pass_x (x:int) : (int -> int) -> (int -> int) =
fun (f:int -> int) ->
fun (y:int) ->
f (y + x)
let foo (x : int) : (int -> int) -> (int -> int) =
fun (f : int -> int) (y:int) ->
((next 1) |> pass_x) f y
In contrast pass_x
also returns a lambda function, but this time the return type of pass_x
agrres with the argument types and the return type of the returned lambda function.
Thanks in advance!
Upvotes: 0
Views: 136
Reputation: 17038
A simple way to understand this is that the type arrow is right associative. So int -> int -> int
means int -> (int -> int)
, not (int -> int) -> int
.
Upvotes: 1
Reputation: 243051
If you write a type of a function without any parentheses, it is interpreted as a function written in a curried form, i.e. a function that takes the first argument and returns a function taking further arguments.
This means that int -> int -> int -> int
means the same thing as:
int -> (int -> (int -> int))
This is different from the return type of foo
which is:
(int -> int) -> (int -> int)
Or, written without the sectond pair of parentheses, which is optional:
(int -> int) -> int -> int
The difference is that:
The former is a function that takes int
, returns a function taking another int
which returns a function taking one more int
and returns an int
- equivalently, this is a function taking three integers and returning another one.
The latter is a function that takes a function (int -> int
) and returns a function taking an int
and returning an int
.
In other words, one is a function taking three numbers whereas the other is a function taking a function and a number.
Upvotes: 1