5
votes

When I set parenthesis in a function definition, the function types change.

I have two functions: addition1(without parenthesis) and addition2 (with parenthesis). The types are the same, but the function signature is different. Why is the type different?

let addition1 a b =
  a + b
//val addition1 : a:int -> b:int -> int

let addition2(a, b) = 
  a + b
//val addition2 : a:int * b:int -> int
1
You also added a comma which is the big change - John Palmer
It's not the same, first function is taking two parameters (actually taking first parameter then creating a function taking the second parameter). And can be curried. Second function is taking one parameter, that is a tuple. First form is common for F# code, second one is more for interop with BCL. - s952163
@s952163 I understand. Is there some significant difference? - John Doe

1 Answers

9
votes

The types are the same, but the function signature is different. Why the type different?

The types aren't actually the same.

When you write:

let addition1 a b = a + b

You create a function which is distinctly different than

let addition2 (a, b) = a + b

In the second case, the parenthesis and comma are creating a tuple, meaning that your function accepts a single parameter, which is a tuple (typed as int * int), and returns an int.

The first case creates a function which can be curried. The type signature of int -> int -> int means that it creates a function which accepts an int, and then returns a function which accepts and int and returns an int. This allows you to use partial application:

let partially_applied_addition1 = addition1 3

For details, see functions in the official docs, and Currying from fsharpforfunandprofit.

Allowing for currying is much more common in F# code. In general, using tuples as a parameter is mostly done for interop scenarios with the base class libraries or when planning an API to be used from C# or other languages. Being able to partially apply allows things like piping to work properly:

let answer =
    getSomeIntegerValue ()
    |> addition1 12 // Add 12 to result

The tupled form will not compile with the above, as it cannot work with partial application.