递归地将列表解压缩为元素

时间:2016-02-23 07:58:05

标签: 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(rnds))
List.head(List.tail(List.tail(rnds)))
List.head(List.tail(List.tail(List.tail(List.tail(rnds)))))

不幸的是,我尝试使用折叠或扫描的递归解决方案甚至更好的尝试都没有成功。例如,这只返回列表(与map相同)。

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

2 个答案:

答案 0 :(得分:5)

uncons能做你需要的吗?

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

答案 1 :(得分:2)

对于一个班级来说,这似乎是一个很好的机会

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