6

对我来说,这似乎是一个虚构的并发症。为了反转序列(可枚举),必须先将其转换为列表。这是为什么?

4

4 回答 4

6

由于您不能向后遍历序列,因此列表是反转序列的理想存储介质。当你建造它们时,它们甚至有反转的趋势,去想一想。

不过,我不知道为什么rev首先不在 Seq 模块中。甚至 LINQ 也有一个Reverse()运算符。幸运的是,它很容易实现。

let rev xs = Seq.fold (fun acc x -> x::acc) [] xs

另一种选择是只使用 LINQ 的运算符。

let rev = System.Linq.Enumerable.Reverse
于 2013-09-20T14:01:38.043 回答
4

为什么还没有rev其他函数消耗整个序列(length, sortBy, groupBy)?从根本上说,为什么任何函数都是包含在标准库中的好选择?我会大胆猜测,这与其说是一套精确的规则,不如说是一个击中“最佳位置”的问题。例如,它是否是一个很好的交叉点:有用、预期、性能、鼓励良好实践、......有点主观(这就是这个问题最终无法回答的原因)但实用,并且在大多数情况下是直观的。

于 2013-09-20T14:12:47.863 回答
3

实现的APISeq本质上有两个功能

  1. 获取下一项
  2. 我们在名单的最后吗

结果,无法检查列表的长度。枚举也可能非常昂贵,因为没有结果缓存,甚至可能导致副作用发生。

此外,序列可能是无限的。

结果,我们没有Seq.rev,我们需要先使用转换到另一个序列。

于 2013-09-20T04:20:24.580 回答
2

当您拥有大量有序的数据集合但不一定希望使用所有元素时,序列特别有用。仅根据需要计算单个序列元素,因此在并非使用所有元素的情况下,序列可以提供比列表更好的性能 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
于 2013-09-20T05:38:04.647 回答