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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With