Em F#, tudo o que tem um tipo e pode ser definido é chamado de valor. Isso inclui Boolean, inteiros e listas, mas também funções. Valores inteiros são definidos como um ou mais dígitos (consecutivos) e dão suporte aos operadores matemáticos padrão.
Atribuir um valor a um nome é chamado de binding. Os bindings são imutáveis, o que os torna parecidos com constantes em outras linguagens. Os bindings são definidos com a palavra-chave let.
Como F# é uma linguagem de tipagem estática, cada binding tem um tipo. Especificar o tipo de um binding é opcional na maioria deles, já que a inferência de tipos do F# normalmente consegue deduzir o tipo com base no valor.
// Automatically inferred type
let fingers = 10
As funções também são bindings comuns, mas com um ou mais parâmetros. Uma função retorna automaticamente a sua última expressão. A inferência de tipos também funciona para a maioria das funções, analisando com quais valores a função é chamada e qual valor ela retorna.
// Automatically inferred types for parameters and return type
let add x y = x + y
Para chamar uma função, escreva o nome dela e passe um argumento para cada parâmetro da função.
let five = add 2 3
Se o tipo de um binding não puder ser inferido, o compilador vai reportar um erro. Para resolver isso, deixe o tipo do binding explícito.
// Explicit type annotation
let fingers: int = 10
// Explicit type annotation (also for parameters)
let add (x: int) (y: int): int = x + y
Os bindings em F# só podem ser usados depois de definidos. Usar um binding antes de defini-lo resulta em um erro de compilação.
// Compile error as the add binding has not yet been defined
// let seven = add 3 + 4
let add x y = x + y
Espaços em branco significativos são usados para definir o escopo, indentando o código com espaços em relação à linha que declara o binding. A convenção padrão é usar quatro espaços para a indentação.
let toes =
let left = 5
let right = 5
left + right
let multiplyPlusTwo x y =
let product = x * y
product + 2
// Trying to access the left, right or product bindings
// here would result in a compile error
Os bindings em F# (que incluem as funções) normalmente são organizados em módulos. Um módulo agrupa funcionalidades relacionadas e é definido com a palavra-chave module. A definição do módulo deve vir antes dos seus bindings:
module Calculator
let pi = 3.14
let add x y = x + y
O F# dá suporte a dois tipos de comentários. Comentários de uma linha são precedidos por //, e comentários de várias linhas ficam entre (* e *).