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.

Voir aussi