John Doe
John Doe

Reputation: 493

Parenthesis change the function signature

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

Answers (1)

Reed Copsey
Reed Copsey

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

Related Questions