Question

I have a question regarding two types int -> (int -> int) and (int -> int) -> int. What is the difference between these two?

I read here somewhere that the first one could be interpreted as a function that that takes an int and returns a function that takes and int and returns an int, which is the same as int ->int -> int. Is this right?

Was it helpful?

Solution

The difference between int -> (int -> int) and int -> int -> int is negligible (you would really only care if you had to interop with another language). These are curried functions which effectively take two integers and return an integer (for example, the built-in addition operator has a type along these lines).

However, both of these are very different from (int -> int) -> int, which takes a function from integers to integers and returns an integer. As others have mentioned, the only simple example of such a function would apply the given function to a specific value (e.g. fun (f:int->int) -> f 13).

OTHER TIPS

Good question, I suspect that functionally there's not much difference. I spent a while fiddling around trying to work out how to even get those two signatures. (John Palmer's let fun1 i = fun j -> i + j just gives int -> int -> int for me)

let add a b = a + b       // int -> int -> int
let inc a = add a         // int -> (int -> int)

I couldn't think of a non-contrived example for the second signature:

let foo fn : int -> fn 1  // (int -> int) -> int

(This doesn't directly answer your question, but may give someone else something to chew on)

I dont really know F#, but it seems quite intuitive (many other language have the same notions).

  1. Is a function taking an int, and returning a function that takes an int and returns an int
  2. Is a function taking a function that takes an int and returns an int, and returning an int

The first would be kind of like curried function.

So lets see what implementations would look like:

first

let func1 i = fun j -> i+j

this has a signature of int -> (int -> int)

note that func1 2 3 shouldn't work

EDIT: It turns out that due to the way associativity works this is actually fine

but this is different to

let func2 i j= i+j

which has a type of int -> int -> int

here func2 1 2 is fine

the other example we can create like this:

let func4 a = a 1

this will have a signature of ('t->int) -> u picking a concrete a will work. Note that func4 1 2 will definitely not compile

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top