Результат равен , но вы используете разные способы их печати. Если вместо Js.log
вы используете rtop
или эскиз. sh, вы получите ожидаемый результат:
- : list(int) = [11, 22, 33]
Js.log
печатает его по-другому, потому что это привязка BuckleScript к console.log
, которая будет печатать JavaScript -представление значения, которое вы ему дадите. И списки не существуют в JavaScript, только в массивах.
BuckleScript представляет списки почти так же, как это делается изначально. Список в OCaml и Reason - это «cons-ячейка», которая по сути является кортежем или двухэлементным массивом, где первый элемент - это значение этой ячейки, а последний элемент - указатель на следующую ячейку. Тип list
по существу определяется так:
type list('a) =
| Node('a, list('a))
| Empty;
И с этим определением можно было бы построить с помощью:
Node(11, Node(22, Node(33, Empty)))
, который представлен в JavaScript следующим образом:
[11,[22,[33,0]]]
^ ^ ^ ^
| | | The Empty list
| | Third value
| Second value
First value
Списки определяются таким образом, потому что неизменность делает это представление очень эффективным. Потому что мы можем добавлять или удалять значения, не копируя все элементы старого списка в новый. Чтобы добавить элемент, нам нужно создать только одну новую "cons-ячейку". Используя представление JavaScript с воображаемой неизменностью:
const old = [11,[22,[33,0]]];
const new = [99, old];
И чтобы удалить элемент спереди, нам не нужно ничего создавать. Мы можем просто получить ссылку и повторно использовать подсписок, потому что мы знаем, что он не изменится.
const old = [11,[22,[33,0]]];
const new = old[1];
Недостатком списков является то, что добавление и удаление элементов до конца относительно дорого. Но на практике, если вы структурируете свой код функционально, используя рекурсию, список будет очень естественным для работы. И очень эффективно.