Reputation: 493
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
Upvotes: 5
Views: 272
Reputation: 564373
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.
Upvotes: 9