Как объединить списки в erlang без создания вложенных списков?

Я пытаюсь быть хорошим erlanger и избежать "++". Мне нужно добавить Кортеж в конец списка без создания вложенного списка (и, надеюсь, без необходимости строить его назад и обращать вспять). Данный кортеж T и списки L0 и L1:

когда я использую [T|L0] Я [кортежа,list0].

но когда я использую [L0/T], Я получаю вложенный список [[list0] / tuple]. Аналогично,[L0|L1] возвращает [[list0] / list1].

удаление скобок внешнего списка L0 / [T] производит синтаксическую ошибку.

Почему "|" не симметрично? Есть ли способ сделать то, что я хочу, используя "|"?

1 ответов


| не является "симметричным", потому что непустой список имеет головку и хвост, где голова является одним элементом, а хвост-другим списком. В выражении [foo | bar] foo обозначает начало списка и bar - это хвост. Если хвост не является правильным списком, результат также не будет правильным списком. Если голова-это список, результатом будет просто список с этим списком в качестве первого элемента.

нет способа добавить в конце связанного списка менее чем за O(n) время. Вот почему использование ++ для этого обычно избегают. Если бы в конце списка был добавлен специальный синтаксис, ему все равно потребовалось бы время O (n), и использование этого синтаксиса не сделало бы вас более "хорошим erlanger", чем использование ++ будет.

если вы хотите избежать стоимости O(n) за вставку, вам нужно будет добавить, а затем отменить. Если вы готовы оплатить стоимость, вы можете просто использовать ++.

немного подробнее о том, как списки работа:

[ x | y ] это то, что называется ячейкой минусов. В терминах C это в основном структура с двумя членами. Правильный список-это либо пустой список ([]) или ячейка минусов, второй член которой является правильным списком (в этом случае первый член называется его головой, а второй член называется его хвостом).

поэтому, когда вы пишите [1, 2, 3] это создает следующие недостатки клетки: [1 | [2 | [3 | []]]]. Т. е. список представлен как ячейка минусов, первый член которой (ее глава) равен 1 и второй член (хвост) - Еще одна ячейка минусов. Что другие минусы клетка имеет 2 главе и еще минусы клетку как свой хвост. Эта ячейка имеет 3 в качестве головы и пустой список в качестве хвоста.

обход такого списка выполняется рекурсивно, сначала действуя на начало списка, а затем вызывая функцию обхода в конце списка.

теперь, если вы хотите добавить элемент в этот список, это очень просто: вы просто создаете другую ячейку минусов, голова которой новый пункт и чей хвост-старый список.

добавление элемента, однако, намного дороже, потому что создание одной ячейки минусов недостаточно. Вы должны создать список, который совпадает со старым, за исключением того, что хвост последней ячейки минусов должен быть новой ячейкой минусов, голова которой является новым элементом, а хвост-пустым списком. Таким образом, вы не можете добавить список, не пройдя через весь список, который является O(n).