Я пытаюсь изучить F #, переписав некоторые алгоритмы C #, которые у меня есть. идиоматический F #.
Одна из первых функций, которую я пытаюсь переписать, - это bchesOf where:
[1..17] |> batchesOf 5
Которая разбивает последовательность на партии, максимум пять в каждой, то есть:
[[1; 2; 3; 4; 5]; [6; 7; 8; 9; 10]; [11; 12; 13; 14; 15]; [16; 17]]
Моя первая попытка сделать это любезна уродливого, когда я прибегал к использованию изменяемого объекта 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 .