Options
Le type d’option en F# est utilisé lorsqu’une valeur réelle risque de ne pas exister pour une valeur ou variable nommée. Une option a un type sous-jacent et peut soit contenir une valeur de ce type, soit ne pas avoir de valeur.
Notes
Le code suivant illustre une fonction qui génère un type d’option.
let keepIfPositive (a: int) = if a > 0 then Some(a) else None
Comme vous pouvez le voir, si l’entrée a
est supérieure à 0, Some(a)
est généré. Sinon, None
est généré.
La valeur None
est utilisée lorsqu’une option n’a pas de valeur réelle. Sinon, l’expression Some( ... )
donne une valeur à l’option. Les valeurs Some
et None
sont utiles dans les critères spéciaux, comme dans la fonction exists
suivante, qui retourne true
si l’option a une valeur et false
si elle n’en a pas.
let exists (x: int option) =
match x with
| Some(x) -> true
| None -> false
Utilisation d’options
Les options sont couramment utilisées lorsqu’une recherche ne retourne pas de résultat correspondant, comme indiqué dans le code suivant.
let rec tryFindMatch pred list =
match list with
| head :: tail -> if pred (head) then Some(head) else tryFindMatch pred tail
| [] -> None
// result1 is Some 100 and its type is int option.
let result1 = tryFindMatch (fun elem -> elem = 100) [ 200; 100; 50; 25 ]
// result2 is None and its type is int option.
let result2 = tryFindMatch (fun elem -> elem = 26) [ 200; 100; 50; 25 ]
Dans le code précédent, une liste fait l’objet d’une recherche récursive. La fonction tryFindMatch
prend une fonction de prédicat pred
qui retourne une valeur booléenne et une liste à rechercher. Si un élément qui satisfait au prédicat est trouvé, la récursion se termine et la fonction retourne la valeur en tant qu’option dans l’expression Some(head)
. La récursion prend fin lorsque la liste vide correspondante. À ce stade, la valeur head
n’a pas été trouvée et None
est retourné.
De nombreuses fonctions de bibliothèque F# qui recherchent une valeur dans une collection susceptible d’exister ou non retournent le type option
. Par convention, ces fonctions commencent par le préfixe try
, par exemple, Seq.tryFindIndex
.
Les options peuvent également s’avérer utiles lorsqu’une valeur est susceptible de ne pas exister, par exemple, s’il est possible qu’une exception soit levée lorsque vous essayez de construire une valeur. L'exemple de code suivant illustre ceci.
open System.IO
let openFile filename =
try
let file = File.Open(filename, FileMode.Create)
Some(file)
with ex ->
eprintf "An exception occurred with message %s" ex.Message
None
La fonction openFile
de l’exemple précédent a un type string -> File option
, car elle retourne un objet File
si le fichier s’ouvre correctement et None
si une exception se produit. Selon la situation, le choix d’intercepter une exception plutôt que de lui permettre de se propager peut ne pas être judicieux.
En outre, il est toujours possible de passer null
ou une valeur null au cas Some
d’une option. Ce choix doit généralement être évité et s’avère courant dans la programmation F# de routine, mais il est possible en raison de la nature des types de référence dans .NET.
Méthodes et propriétés des options
Le type d’option prend en charge les propriétés et méthodes suivantes.
Propriété ou méthode | Type | Description |
---|---|---|
None |
'T option |
Membre statique qui crée une valeur d’option qui a la valeur None . |
IsNone | bool |
Retourne true si l’option a la valeur None . |
IsSome | bool |
Retourne true si l’option a une valeur qui n’est pas None . |
Some |
'T option |
Membre statique qui crée une option qui a une valeur qui n’est pas None . |
Valeur | 'T |
Retourne la valeur sous-jacente ou lève une System.NullReferenceException si la valeur est None . |
Module Option
Il existe un module, Option, qui contient des fonctions utiles qui effectuent des opérations sur les options. Certaines fonctions répètent les fonctionnalités des propriétés, mais elles s’avèrent utiles dans les contextes où une fonction est nécessaire. Option.isSome et Option.isNone sont des fonctions de module qui testent si une option contient une valeur. Option.get obtient la valeur, le cas échéant. En l’absence de valeur, elle lève System.ArgumentException
.
La fonction Option.bind exécute une fonction sur la valeur, s’il en existe une. La fonction doit prendre exactement un seul argument et son type de paramètre doit être le type d’option. La valeur renvoyée de la fonction est un autre type d’option.
Le module Option inclut également des fonctions qui correspondent aux fonctions disponibles pour les listes, les tableaux, les séquences et d’autres types de collection. Ces fonctions incluent Option.map
, Option.iter
, Option.forall
, Option.exists
, Option.foldBack
, Option.fold
et Option.count
. Ces fonctions permettent d’utiliser des options comme une collection de zéro ou d’un élément. Pour plus d’informations et d’exemples, consultez la discussion sur les fonctions de collection dans Listes.
Conversion en d’autres types
Les options peuvent être converties en listes ou tableaux. Lorsqu’une option est convertie en l’une ou l’autre de ces structures de données, la structure de données obtenue a zéro ou un élément. Pour convertir une option en tableau, utilisez Option.toArray
. Pour convertir une option en liste, utilisez Option.toList
.