Recursion 递归地将列表解包为元素

Recursion 递归地将列表解包为元素,recursion,f#,mutable,Recursion,F#,Mutable,我有一个列表,并希望从中分别返回每个元素。基本上就像从堆栈中弹出一样。例如: let rnd = new System.Random() let rnds = List.init 10 (fun _ -> rnd.Next(100)) List.iter (fun x -> printfn "%A"x ) rnds 但是,我实际上不想迭代,而是一个接一个地返回每个整数,直到列表为空。所以基本上是这样的: List.head(rnds) List.head(List.tail(rnd

我有一个列表,并希望从中分别返回每个元素。基本上就像从堆栈中弹出一样。例如:

let rnd = new System.Random()
let rnds = List.init 10 (fun _ -> rnd.Next(100))
List.iter (fun x -> printfn "%A"x ) rnds
但是,我实际上不想迭代,而是一个接一个地返回每个整数,直到列表为空。所以基本上是这样的:

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)))))
不幸的是,我尝试使用fold或scan的递归解决方案,甚至更好的解决方案都没有成功。例如,这只是返回列表(与map相同)


这似乎是一个很好的机会

type unpacker(l) = 
    let mutable li = l
    member x.get() = 
        match li with
        |h::t -> li<-t;h
        |_ -> failwith "nothing left to return"
类型拆包器(l)=
设可变li=l
成员x.get()=
与李相配
|h::t->li故障,无需返回

你会做你需要的事吗

let uncons = function h::t -> Some (h, t) | [] -> None
您可以使用它“弹出”列表的标题:

> rnds |> uncons;;
val it : (int * int list) option =
  Some (66, [17; 93; 33; 17; 21; 1; 49; 5; 96])
您可以重复以下步骤:

> 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])

所以我会像这样使用它:
let xx=unpacker(rnds)
xx.get()
或“[for I in 1..5->xx.get()]”我添加了
覆盖这个。ToString()=sprintf“%A”l
,以使它更易于使用。是的,的确,这也是一个非常有趣的解决方案。非常感谢。
> 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])