【发布时间】:2011-09-22 05:19:21
【问题描述】:
我正在尝试通过将一些 C# 算法重写为惯用的 F# 来学习 F#。
我尝试重写的第一个函数是 batchesOf,其中:
[1..17] |> batchesOf 5
这会将序列分成批次,每个批次最多五个,即:
[[1; 2; 3; 4; 5]; [6; 7; 8; 9; 10]; [11; 12; 13; 14; 15]; [16; 17]]
我第一次尝试这样做有点难看,在尝试在闭包内使用 mutable 类型时遇到错误后,我求助于使用可变 ref 对象.使用 ref 尤其令人不快,因为要取消引用它,您必须使用 ! 运算符,当在条件表达式中时,对于一些将其读取为 不合逻辑。我遇到的另一个问题是 Seq.skip 和 Seq.take 与它们的 Linq 别名不同,如果 size 超过序列的大小,它们会抛出错误。
let batchesOf size (sequence: _ seq) : _ list seq =
seq {
let s = ref sequence
while not (!s |> Seq.isEmpty) do
yield !s |> Seq.truncate size |> List.ofSeq
s := System.Linq.Enumerable.Skip(!s, size)
}
无论如何,用 F# 重写它的最优雅/惯用的方法是什么?保持原始行为,但最好不使用 ref 可变变量。
【问题讨论】:
-
隐约related
-
另见 Deedle 中的“分块”操作:bluemountaincapital.github.io/Deedle/timeseries.html#windowing(来自@Tomas Petricek)
标签: linq f# functional-programming sequence