2016-02-23 27 views
5

Ho una lista e desidero restituire ciascun elemento singolarmente. Fondamentalmente come scoppiare da una pila. Ad esempio:Estrarre ricorsivamente l'elenco negli elementi

let rnd = new System.Random() 
let rnds = List.init 10 (fun _ -> rnd.Next(100)) 
List.iter (fun x -> printfn "%A"x) rnds 

Tuttavia, invece di iterazione, avrei effettivamente desidero restituire ogni intero uno dopo l'altro finché l'elenco è vuoto. Quindi, in pratica qualcosa sulla falsariga di:

List.head(rnds) 
List.head(List.tail(rnds)) 
List.head(List.tail(List.tail(rnds))) 
List.head(List.tail(List.tail(List.tail(List.tail(rnds))))) 

purtroppo il mio tentativo di una soluzione ricorsiva o meglio ancora qualcosa usando volte o scansione non hanno avuto successo. Ad esempio questo restituisce solo la lista (come la mappa).

let pop3 (rnds:int list) = 
    let rec pop3' rnds acc = 
     match rnds with 
     | head :: tail -> List.tail(tail) 
     | [] -> acc 
    pop3' [] rnds 

risposta

2

Questo mi sembra un buon oppurtunity per una classe

type unpacker(l) = 
    let mutable li = l 
    member x.get() = 
     match li with 
     |h::t -> li<-t;h 
     |_ -> failwith "nothing left to return" 
+0

Quindi mi sento di usarlo come: 'lasciare xx = unpacker (rnds) '' xx.get() 'o' [per i in 1..5 -> xx.get()] 'Ho aggiunto' override this.ToString() = sprintf "% A" l' per creare è un po 'più user friendly. – s952163

5

Would uncons fai quello che ti serve?

let uncons = function h::t -> Some (h, t) | [] -> None 

È possibile utilizzarlo per 'pop' il capo di una lista:

> rnds |> uncons;; 
val it : (int * int list) option = 
    Some (66, [17; 93; 33; 17; 21; 1; 49; 5; 96]) 

È possibile ripetere questo:

> rnds |> uncons |> Option.bind (snd >> uncons);; 
val it : (int * int list) option = Some (17, [93; 33; 17; 21; 1; 49; 5; 96]) 
> rnds |> uncons |> Option.bind (snd >> uncons) |> Option.bind (snd >> uncons);; 
val it : (int * int list) option = Some (93, [33; 17; 21; 1; 49; 5; 96]) 
+0

Sì, davvero una soluzione molto interessante. Grazie mille. – s952163