MrFranzén
MrFranzén

Reputation: 127

Return type of a function returning a lambda function

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

Answers (2)

Brian Berns
Brian Berns

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

Tomas Petricek
Tomas Petricek

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

Related Questions