You are previewing Programming F#.

Programming F#

Cover of Programming F# by Chris Smith Published by O'Reilly Media, Inc.
O'Reilly logo


Now that we have all of F#’s primitive types under our control, let’s define functions in order to manipulate them.

You define functions the same way you define values, except everything after the name of the function serves as the function’s parameters. The following defines a function called square that takes an integer, x, and returns its square:

> let square x = x * x;;

val square : int -> int

> square 4;;
val it : int = 16

Unlike C#, F# has no return keyword. So when you define a function, the last expression to be evaluated in the function is what the function returns.

Let’s try another function to add 1 to the function’s input:

> let addOne x = x + 1;;

val addOne : int -> int

The output from FSI shows the function has type int -> int, which is read as “a function taking an integer and returning an integer.” The signature gets a bit more complicated when you add multiple parameters:

> let add x y = x + y

val add : int -> int -> int

Technically speaking, the type int -> int -> int is read as “a function taking an integer, which returns a function which takes an integer and returns an integer.” Don’t worry about this “functions returning functions” jazz just yet. The only thing you need to know for now is that to call a function, simply provide its parameters separated by spaces:

> add 1 2;;

Val it : 3

Type Inference

Because F# is statically typed, calling the add method you just created with a floating-point value will result in a compiler error:

> add 1.0 2.0;; add 1.0 2.0;; ...

The best content for your career. Discover unlimited learning on demand for around $1/day.