Мне кажется, вы начинаете работать с OCaml и имеете опыт программирования.Вероятно, лучший совет для размышления об OCaml (и функциональном программировании в целом) - начать думать обо всех конструкциях вашей программы как о выражениях, то есть о вещах со значениями.В императивном программировании многие вещи (например, цикл for, цикл while, оператор if) не имеют значений, они просто «делают» вещи.В функциональном программировании все имеет значение.
Поскольку OCaml не является функциональным языком pure , одно значение зарезервировано для представления выражения, которое просто «что-то» делает.Значение записывается так: ()
.Тип этого значения известен как unit
(это единственное значение типа unit
).
Поскольку цикл for
предназначен для того, чтобы просто «делать» вещи, даже в OCaml,выражение внутри цикла должно иметь тип unit
.Но вы написали что-то, что имеет тип списка.Все, что выглядит как x :: y
, должно быть списком, потому что конструктор ::
создает список.Это то, о чем вас предупреждает компилятор.Внутри вашего цикла должен быть тип unit
, но у него есть тип списка.
Ваша вторая проблема заключается в том, что выражение x :: y
не не меняет значение y
,Это суть функционального программирования.Все, что делает выражение, это вычисляет новое значение (список).Это не меняет ни одно из значений, которые появляются в выражении.Из-за этого acc
заканчивается тем же значением, с которого оно начиналось.
Я бы действительно предложил вам решить эту проблему с помощью рекурсии (как это было предложено Бэзилом Старынкевичем), а не пытаться использовать императивные конструкции, такие какцикл for
.Это приведет к гораздо более идиоматическому коду OCaml.Если вам действительно необходимо использовать цикл for
по какой-либо причине, вам нужно сделать переменную acc
изменяемым значением, и вам нужно изменить (изменить) ее в цикле.