07 March 2026

Functions in F#

In learning about F#, one of the first things I had to come to terms with is that all F# functions have only one input and only one output.

This is a strange thing to understand when you’re allowed to write things like:

> let add x y = x + y;;

Even though it’s clear we’re returning one integer, it sure looks like we’re passing two arguments to add.

In reality, what’s happening becomes a bit clearer if we examine the function’s type signature:

val add: x: int -> y: int -> int

What this is saying is that add is a function that takes an int x and returns a function that takes int y and returns an int. Think of each arrow (->) as a function that takes the parameter from the left and returns the value to the right. This is called Currying, which is apparently named after the guy who invented Haskell.

Therefore, we can pass an integer, say 5, to the function add, and it will return another function which will take an interger, add it to 5, and then return the result. If we name that new function add5, we can define it as follows:

> let add5 = add 5;;

which gives us the type signature of

val add5: (int -> int)

Calling add5 with another integer gives us the sum:

> add5 4;;
val it: int = 9

> add5 -7;;
val it: int = -2

We can also partially define other such functions by just passing the first argument to add:

> let add7 = add 7;;
val add7: (int -> int)

> let add10 = add 10;;
val add10: (int -> int)

> add7 4;;
val it: int = 11

> add10 20;;
val it: int = 30

Unsurprisingly, this concept is called Partial Application.