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:

>;; val square : int -> int > square 4;; val it : int = 16`let square x = x * x`

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

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;; ...