Прежде всего, для этого уже есть приложение - оно называется Array.chunkBySize
:
> Array.chunkBySize 2 [|1;2;3;4;5;6;7|]
val it : int [] [] = [|[|1; 2|]; [|3; 4|]; [|5; 6|]; [|7|]|]
И в Seq
и List
есть аналогичные функциимодуля, так что если ваша цель - работать со строками, я бы рассмотрел вариант Seq
, поскольку string
уже реализует интерфейс seq
:
> Seq.chunkBySize 2 "abcdefg";;
val it : seq<char []> =
seq [[|'a'; 'b'|]; [|'c'; 'd'|]; [|'e'; 'f'|]; [|'g'|]]
Но если вы 'Если вы заинтересованы в образовании, а не в GSD, то вот оно:
Логика кода прекрасна, за исключением того, что у вас есть несколько чисто синтаксических ошибок и одна логическая.
Первый , тип "массив из" не обозначен array 'a
.В общем случае обозначение F # для универсальных типов имеет вид T<'a>
или 'a T
, например list<int>
или int list
.Однако это не работает для массивов, потому что массивы особенные.Существует тип System.Array
, но он не является общим, поэтому его нельзя использовать таким образом.Вместо этого идея массива как бы встраивается в CLR, поэтому вы должны использовать специальный синтаксис: 'a[]
.
Итак: a : 'a[]
вместо a : array 'a
Second , хотя у массива есть свойство length, оно пишется с заглавной буквы (т. Е. Length
) и это свойство, а не метод, поэтому после него не должно быть скобок.
Итак: a.Length
вместо a.length()
Однако это не совсем F # способ.Методы и свойства - лучше, функции - лучше.Путь F # заключается в использовании функции Array.length
.
Итак: Array.length a
вместо a.length()
Бонус: если вы это сделаете, нет необходимости в аннотации типа: 'a[]
, потому что компилятор теперь может выяснить это по типу Array.length
.
Третий , для индексации массивов, списков и всего остального, имеющего индекс, требуетсяточка перед открывающей скобкой.
Итак: a.[ind .. (ind + n - 1)]
вместо a[ind .. (ind + n - 1)]
Четвертый , in
не является необходимым в F #.Вы можете просто опустить его.
С вышеуказанными модификациями ваша программа будет работать.Но только для массивов, длина которых кратна n
.На всех остальных вы получите IndexOutOfRangeException
.Это потому, что у вас также есть ...
Логическая ошибка в том, что когда вы проверяете, что ind
находится в пределах массива, вы не проверяете, что ind + n - 1
как хорошо.Итак, вам нужен третий случай в вашей ветке:
if ind >= Array.length a then
[]
elif ind + n - 1 >= Array.length a then
a.[ind..] :: r (ind+n)
else
a.[ind .. (ind+n-1)] :: r (ind+n)
Теперь все готово для прайм-тайма.