Почему я получаю единицу типа, когда хочу объединить элемент массива с пустым списком?

#arrays #list #concatenation #ocaml #imperative-programming

Вопрос:

Я пытаюсь составить список из заданного массива, и в моем коде он возвращает пустой список. Я хочу знать, почему это невозможно сделать со списком. Это потому, что мы должны вернуть что-то в третьей строке, а объединение нигде не «сохранено»?

 let arrayTOlist a = let l =[] in
  for i=0 to (Array.length a -1) do 
    [a.(i)]::l      (*why does this have type unit?*) 
  done;
  l;;
 

Ответ №1:

Значение l в вашем коде является неизменяемым. Таким образом, ничто не может изменить его от первоначального значения [] . Таким образом, функция всегда будет возвращаться [] .

Выражение [a.(i)] :: l лица не меняется l . Он имеет значение, представляющее собой список длиной 1 для каждой итерации. Затем это значение отбрасывается (что приводит к предупреждению о том, что значение должно иметь тип unit).

Функция уже существует Array.to_list , поэтому я предполагаю, что это проблема домашней работы, и, следовательно, нет смысла повторно Array.to_list использовать другие функции из модуля массива.

Лучший способ продолжить, вероятно, заключается в рекурсивной функции, которая принимает индекс массива в качестве параметра.

Ответ №2:

Если мы попробуем выполнить следующее, это не вызовет никакого предупреждения..

 let arrayTOlist a = let l =[] in [a.(0)] :: l;;
val arrayTOlist : 'a array -> 'a list list = <fun>
 

поэтому я твердо верю, что это цикл for, из-за которого генерируется это предупреждение.

Мы можем найти более подробную информацию об этом поведении, прочитав раздел о цикле for в документации OCaml.