Uma expressão if/elif/else pode ser usada para executar lógica condicionalmente. O F# também tem outra forma, mais poderosa, de o fazer: correspondência de padrões. Com a correspondência de padrões, um valor pode ser testado em relação a um ou mais padrões. Um exemplo desse tipo de padrão é o padrão constante, que faz corresponder um valor a uma constante (por exemplo, 1 ou "hello").
Em F#, a correspondência de padrões é feita através da palavra-chave match:
let describe number =
match number with
| 0 -> "Zero"
| 1 -> "One"
Embora isto possa parecer instruções switch de outras linguagens, a correspondência de padrões começa a destacar-se quando também se usam outros padrões. Um desses padrões é o padrão variável, que permite capturar um valor:
match number with
| 0 -> "Zero"
| i -> sprintf "Non zero: %d" i
Em alguns casos, podes querer adicionar uma condição adicional a um padrão. Isto é conhecido como uma cláusula de guarda, que pode ser adicionada com a palavra-chave when:
match number with
| 0 -> "Zero"
| i when i < 0 -> "Negative number"
Uma cláusula de guarda pode ser qualquer expressão válida, incluindo chamar funções.
No exemplo acima, nem todos os valores de entrada possíveis terão um padrão correspondente. O compilador deteta isto e emite um aviso. Isto é conhecido como correspondência exaustiva. Para resolver o aviso, é preciso tratar todos os casos. Para isso, pode usar-se o [padrão universal][wildcard-pattern], que é um padrão que corresponde a qualquer valor:
match number with
| i when i < 0 -> "Negative number"
| _ -> "Positive number"
// No compiler warning
Repara que o compilador não consegue usar cláusulas when para inferir a exaustividade:
match number with
| i when i < 0 -> "Negative number"
| i when i >= 0 -> "Positive number"
// Compiler warning
A correspondência de padrões testa um valor em relação a cada padrão, de cima para baixo, até encontrar um padrão correspondente e executar a lógica associada a esse padrão. A ordem dos padrões importa! Por isso, o padrão universal deve ser sempre o último padrão numa expressão match.
Embora a correspondência de padrões seja muito poderosa, a lógica condicional simples pode, normalmente, ser expressa de forma mais clara com uma expressão if/else:
let usingPatternMatching number =
match number with
| 0 -> "Zero"
| _ -> "Non-zero"
let usingIfElse number = if number = 0 then "Zero" else "Non-zero"