2009-03-08 6 views
7

? He estado leyendo el libro Expert F # de Apress, usándolo principalmente como referencia cuando construyo una biblioteca de juguetes F #, pero hay algo que no pude comprender y ese es el tipo de "Opción".¿Cómo funciona el tipo de opción en F #

¿Cómo funciona y cuál es su uso en el mundo real?

Respuesta

19

el tipo de opción es al menos similares a Nullable<T> y de referencia tipos en C#. Un valor de tipo Option<T> es None, lo que significa que no hay ningún valor encapsulado, o Some con un valor particular de T. Esto es igual que la forma en que un Nullable<int> en C# es ya sea el valor nulo, o tiene un int asociado - y la forma en un valor String en C# es ya sea una referencia nula, o se refiere a un objeto String .

Cuando se utiliza un valor de opción, por lo general, especificar dos caminos - uno para el caso en que es un valor asociado, y uno donde hay no es. En otras palabras, este código:

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

es similar a:

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

creo que la idea general es que forzando que (bueno, casi) para manejar el "ningún valor/objeto asociado "Case hace que tu código sea más robusto.

2

Lo usa cuando un valor es opcional. Un uso es tener un tipo de 'referencia nula', p.

val x : int option ref = None 

A continuación, puede actualizar más tarde xa Algunos v. Se utiliza con la declaración partido, por ejemplo,

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

Se utiliza cuando una función o método debe "quizás" u "opcionalmente" devolver un valor. En C# probablemente devolverá nulo, o devolverá un Null Object o posiblemente un Nullable para los tipos de valor.

La desventaja de devolver nulo (el caso más común) es que no es seguro de tipo: nulo es una instancia de todos los tipos, por lo que entras en todo tipo de situaciones de referencia nula peluda más adelante.

El tipo de opción es un tipo de unión llamada disciminada con dos constructores: ninguno y algunos a. Ninguna indica explícitamente que no tiene un valor. Básicamente es el patrón Objeto Nulo generalizado.

1

Para agregar a las otras respuestas, el tipo de opción no es nada especial, es simplemente otra unión discriminada.Se podría definir por sí mismo en una sola línea:

type 'a Option = None | Some of 'a 

La utilidad, como otros han señalado, es que la coincidencia de patrones le permitirá deconstruir con seguridad esto, en lugar de la comprobación de nulo o mediante algún artilugio-solución para indicar si un valor no es realmente un valor.

0

Un modelo funcional utilizando el tipo de opción:

Cuando tenga que cambiar partes de una estructura de datos recursiva, como un árbol o una lista, que se desee reutilizar tanto de la estructura de los datos existentes como posible. La opción tipo puede ayudarlo con esto. Estas dos funciones reemplazan todas las ocurrencias del número 5 con 7, pero la primera copia el árbol completo. El segundo 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 

Puede que no sea necesario en todos los casos, pero es una buena técnica para saber.

Cuestiones relacionadas