Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parenthesis change the function signature

Tags:

f#

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
like image 313
John Doe Avatar asked Feb 24 '17 00:02

John Doe


1 Answers

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.

like image 167
Reed Copsey Avatar answered Sep 17 '22 23:09

Reed Copsey