对我来说,这似乎是一个虚构的并发症。为了反转序列(可枚举),必须先将其转换为列表。这是为什么?
4 回答
由于您不能向后遍历序列,因此列表是反转序列的理想存储介质。当你建造它们时,它们甚至有反转的趋势,去想一想。
不过,我不知道为什么rev
首先不在 Seq 模块中。甚至 LINQ 也有一个Reverse()
运算符。幸运的是,它很容易实现。
let rev xs = Seq.fold (fun acc x -> x::acc) [] xs
另一种选择是只使用 LINQ 的运算符。
let rev = System.Linq.Enumerable.Reverse
为什么还没有rev
其他函数消耗整个序列(length
, sortBy
, groupBy
)?从根本上说,为什么任何函数都是包含在标准库中的好选择?我会大胆猜测,这与其说是一套精确的规则,不如说是一个击中“最佳位置”的问题。例如,它是否是一个很好的交叉点:有用、预期、性能、鼓励良好实践、......有点主观(这就是这个问题最终无法回答的原因)但实用,并且在大多数情况下是直观的。
实现的APISeq
本质上有两个功能
- 获取下一项
- 我们在名单的最后吗
结果,无法检查列表的长度。枚举也可能非常昂贵,因为没有结果缓存,甚至可能导致副作用发生。
此外,序列可能是无限的。
结果,我们没有Seq.rev
,我们需要先使用转换到另一个序列。
当您拥有大量有序的数据集合但不一定希望使用所有元素时,序列特别有用。仅根据需要计算单个序列元素,因此在并非使用所有元素的情况下,序列可以提供比列表更好的性能 http://msdn.microsoft.com/en-us/library/vstudio/dd233209.aspx
let rnd = System.Random()
let nums = seq {
let rec getNext() = seq {
yield rnd.Next(100)
yield! getNext()
}
yield! getNext()
}
let len = nums |> Seq.length //nums is an infinite sequence, will not stop