F #, как и многие другие функциональные [-ish] языки, имеет cons-list (терминология изначально взята из LISP, но концепция такая же). В F # оператор ::
(или List.Cons
) используется для получения: обратите внимание, подпись ‘a –> ‘a list –> ‘a list
(см. Мастеринг списков F # ).
Не путайте cons-список с непрозрачной реализацией Linked List, которая содержит дискретный первый [/ last] узел - каждая ячейка в cons-списке является началом [другого] списка! То есть «список» - это просто цепочка ячеек, которая начинается с данной cons-ячейки.
Это дает некоторые преимущества при использовании функционально-подобным образом: во-первых, все «хвостовые» ячейки являются общими и поскольку каждая конс-ячейка является неизменной («данные» могут быть изменяемыми, но это другая проблема) нет способа внести изменения в "хвостовую" ячейку и добавить все остальные списки, которые содержат указанную ячейку.
Из-за этого свойства [новые] списки могут быть эффективно построены, то есть им не требуется копия - просто с помощью cons 'вперед. Кроме того, очень эффективно деконструировать список до head :: tail
- опять же, без копирования - что часто очень полезно в рекурсивных функциях.
Это неизменяемое свойство обычно не существует в реализации [стандартного изменяемого] двойного связанного списка, в этом добавлении добавляются побочные эффекты: внутренний «последний» узел (тип теперь непрозрачный) и одна из «хвостовых» ячеек изменены (Существует типов неизменяемых последовательностей, которые позволяют добавлять / обновлять «эффективно постоянное время», например immutable.Vector в Scala - однако, это более тяжелые объекты по сравнению с минусами -список, представляющий собой не более чем серию ячеек, объединенных вместе.)
Как уже упоминалось, есть и недостатки, что cons-list не подходит для всех задач - в частности, создание нового списка, за исключением cons , связанного с заголовком, является операцией O (n), фсво, а к лучшему (или худшему) список неизменен.
Я бы порекомендовал создать собственную версию concat
, чтобы увидеть, как эта операция действительно выполняется. (Статья Почему я люблю F #: Списки - Основы охватывает это.)
Удачного кодирования.
Также см. Связанный пост: Почему вы можете добавлять к спискам только функциональные языки?