【发布时间】:2011-03-31 00:13:27
【问题描述】:
我正在尝试通过递归地将序列的第一个元素附加到列表中来从序列中构建一个列表:
open System
let s = seq[for i in 2..4350 -> i,2*i]
let rec copy s res =
if (s|>Seq.isEmpty) then
res
else
let (a,b) = s |> Seq.head
Console.WriteLine(string a)
let newS = s |> Seq.skip(1)|> Seq.cache
let newRes = List.append res ([(a,b)])
copy newS newRes
copy s ([])
两个问题:
。得到一个堆栈溢出,这意味着我的尾部递归策略很糟糕
和
。为什么当我将|> Seq.cache 放在这里let newS = s |> Seq.skip(1)|> Seq.cache 时,代码会快100 倍。
(注意这只是一个小练习,我知道你可以做 Seq.toList 等。)
非常感谢
一种可行的方法是(这两点对我来说仍然有点奇怪):
let toList (s:seq<_>) =
let rec copyRev res (enum:Collections.Generic.IEnumerator<_*_>) =
let somethingLeft = enum.MoveNext()
if not(somethingLeft) then
res
else
let curr = enum.Current
Console.WriteLine(string curr)
let newRes = curr::res
copyRev newRes enum
let enumerator = s.GetEnumerator()
(copyRev ([]) (enumerator)) |>List.rev
【问题讨论】:
-
让 newRes = curr :: res - 小改进
标签: f# tail-recursion