2009-03-08 3 views
7

J'ai donc lu le livre Expert F # d'Apress, principalement en l'utilisant comme référence lors de la construction d'une bibliothèque F #, mais il y a une chose que je n'ai pas comprise et c'est le type "Option".Comment le type d'option fonctionne-t-il en F #

Comment cela fonctionne-t-il et quel est son utilisation dans le monde réel?

Répondre

19

Le type d'option est au moins similaire àNullable<T> et types référence en C#. Une valeur de type Option<T> est soit None, ce qui signifie qu'il n'y a pas de valeur encapsulée, soit Some avec une valeur particulière de T. Ceci est tout comme la façon dont un Nullable<int> en C# est soit la valeur nulle, ou a un associé int - et la façon dont une valeur String en C# est soit une référence null, ou fait référence à un objet String .

Lorsque vous utilisez une valeur d'option, vous spécifiez généralement deux chemins - un pour le cas où il est une valeur associée, et celui où il est pas. En d'autres termes, ce code:

let stringLength (str:Option<string>) = 
    match str with 
    | Some(v) -> v.Length 
    | None -> -1 

est similaire à:

int StringLength(string str) 
{ 
    if (str != null) 
    { 
     return str.Length; 
    } 
    else 
    { 
     return -1; 
    } 
} 

Je crois l'idée générale est que forcer vous (bien, presque) pour gérer la « aucune valeur associée/objet "case rend votre code plus robuste.

2

Vous l'utilisez lorsqu'une valeur est facultative. Une utilisation consiste à avoir une sorte de 'référence nulle', par ex. Ensuite, vous pouvez mettre à jour x vers Some v. Vous l'utiliserez avec l'instruction match, par ex.

match !x with (* dereference x *) 
    None -> (* No value, do something *) 
| Some v -> (* Value v, do something else *) 
4

Utilisé lorsqu'une fonction ou une méthode doit "peut-être" ou "éventuellement" renvoyer une valeur. En C# vous renverriez probablement la valeur null, ou retourneriez un Null Object ou éventuellement un Nullable pour les types de valeurs. L'inconvénient de retourner null (le cas le plus courant) est qu'il n'est pas de type safe: null est une instance de tous les types, donc vous entrez dans toutes sortes de situations de référence null poilues plus tard.

Le type d'option est un type d'union dit déconnecté avec deux constructeurs: Aucun et Certains a. Aucun n'indique explicitement que vous n'avez pas de valeur. Fondamentalement, c'est le modèle d'objet nul généralisé.

1

Pour ajouter aux autres réponses, le type d'option n'a rien de spécial - c'est juste une autre union discriminée.Vous pouvez définir vous-même en une ligne:

type 'a Option = None | Some of 'a 

L'utilitaire, comme d'autres l'ont souligné, est que la correspondance de modèle vous permettra de déconstruire en toute sécurité cela, au lieu de vérifier pour nulle ou en utilisant une hack solution de contournement pour indiquer si une valeur n'est pas vraiment une valeur.

0

Un modèle fonctionnel en utilisant le type d'option:

Lorsque vous avez besoin de changer des parties d'une structure de données récursive, comme un arbre ou une liste, vous voudrez réutiliser autant de la structure de données existantes possible. Le type d'option peut vous aider avec ceci. Ces deux fonctions remplacent toutes les occurrences du nombre 5 par 7, mais le premier copie l'arbre entier. Le second ne le fait pas.

type Tree = Leaf of int 
     | Node of Tree * Tree 

let rec replace_no_sharing tree = 
    match tree with 
    | Leaf 5  -> Leaf 7 
    | Leaf x  -> Leaf x 
    | Node (a, b) -> Node (replace_no_sharing a, replace_no_sharing b) 

let replace_with_sharing tree = 
    let rec replace_option tree = 
     match tree with 
     | Leaf 5  -> Leaf 7 |> Some 
     | Leaf x  -> None 
     | Node (a, b) -> match replace_option a, replace_option b with 
         | None, None  -> None 
         | Some a, Some b -> Node (a, b) |> Some 
         | Some a, None -> Node (a, b) |> Some 
         | None, Some b -> Node (a, b) |> Some 
    match replace_option tree with 
    | None  -> tree 
    | Some tree -> tree 

Il pourrait ne pas être nécessaire dans tous les cas, mais il est une belle technique de savoir.