Domanda

Quindi ho letto il libro Expert F # di Apress, per lo più usandolo come riferimento quando ho costruito una libreria F # toy-ish, ma c'è una cosa che non sono riuscito a capire e questa è l'opzione &; " tipo.

Come funziona e qual è il suo utilizzo nel mondo reale?

È stato utile?

Soluzione

Il tipo di opzione è almeno simile a Nullable<T> e tipi di riferimento in C #. Un valore di tipo Option<T> è None il che significa che non esiste un valore incapsulato o Some con un valore particolare di T. Questo è proprio come il modo in cui Nullable<int> in C # è o il valore null, o ha un int associato - e il modo in cui un String valore in C # è o riferimento null, o si riferisce a un oggetto String.

Quando si utilizza un valore di opzione, generalmente si specificano due percorsi: uno per il caso in cui è un valore associato e uno in cui non è . In altre parole, questo codice:

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

è simile a:

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

Credo che l'idea generale sia che forzando tu (beh, quasi) per gestire il " nessun valore / oggetto associato " case rende il tuo codice più robusto.

Altri suggerimenti

È usato quando una funzione o un metodo dovrebbe " forse " oppure " facoltativamente " restituisce un valore. In C # probabilmente restituiresti null o restituiresti un Null Object o possibilmente un Nullable per valore tipi.

Il rovescio della medaglia di restituire null (il caso più comune) è che non è sicuro per i tipi: null è un'istanza di tutti i tipi, quindi ti imbatterai in tutti i tipi di situazioni pelose di riferimento null in seguito.

Il tipo di opzione è un cosiddetto tipo di unione discriminato con due costruttori: nessuno e alcuni a. Nessuno indica esplicitamente che non hai un valore. Fondamentalmente è il modello Null Object generalizzato.

Lo usi quando un valore è facoltativo. Un uso è avere una sorta di "riferimento null", ad es.

 val x : int option ref = None 

Quindi puoi aggiornare x in Some v. Lo usi con l'istruzione match, ad esempio

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

Per aggiungere alle altre risposte, il tipo di Opzione non è niente di speciale: è solo un'altra unione discriminata. Puoi definirlo tu stesso in una riga:

type 'a Option = None | Some of 'a

L'utilità, come altri hanno sottolineato, è che la corrispondenza dei modelli ti consentirà di decostruire in modo sicuro, invece di verificare la presenza di null o utilizzare qualche soluzione alternativa per indicare se un valore non è realmente un valore.

Un modello funzionale che utilizza il tipo di opzione:

Quando è necessario modificare parti di una struttura di dati ricorsiva, come un albero o un elenco, vorrai riutilizzare il più possibile la struttura di dati esistente. Il tipo di opzione può aiutarti in questo. Queste due funzioni sostituiscono entrambe tutte le occorrenze del numero 5 con 7, ma il primo copia l'intero albero. Il secondo no.

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

Potrebbe non essere necessario in tutti i casi, ma è una buona tecnica da sapere.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top