2010-08-23 4 views
38

Tengo inesperadamente un problema al pasar de una lista de 'una opción a una lista que contiene solo los elementos que son Algunos.¿La mejor manera de condensar una lista de tipo de opción para solo elementos que no son ninguno?

Mi primer intento fue:

let ga = List.filter (fun xx -> 
     match xx with 
     | Some(g) -> true 
     | None -> false) gao 

Pero, por supuesto, este tipo de resultado sigue siendo 'una lista de opciones. No sé cómo usar List.map para condensar esto, porque tienes que manejar todos los casos en una declaración de coincidencia. Tengo una solución fea, pero me pregunto si hay algo mejor.

feo:

let rec gOptRemove gdec gacc = 
     match gdec with 
     | head :: tail -> 
      match head with 
      | Some(a) -> gOptRemove tail (a :: gacc) 
      | None -> gOptRemove tail gacc 
     | [] -> gacc 

yo preferiría encontrar una solución no recursivo o averiguar cuál es la forma estándar es para este tipo de cosas.

+0

Ver también 'List.fold_left' –

Respuesta

88

Simplemente

List.choose id 

como en

> [Some 4; None; Some 2; None] |> List.choose id;; 
val it : int list = [4; 2] 

List.choose

id

+2

Wow, eso fue fácil. No tenía idea de que la función existía. –

+1

La razón de esto funciona: List.choose quiere convertir un ''a' en una' opción b'. 'id' es adecuado para esto porque convierte una''c option' en una ''c option'. –

+3

... wow, eso es inteligente. ¿Es así como tu cerebro piensa todo el tiempo? – YotaXP

Cuestiones relacionadas