Learn You a Haskell упоминает списков различий (поиск этого термина на этой странице), где список l
представлен не напрямую а как функция (l ++)
. Это позволяет более эффективно объединять как слева, так и справа. Конкатенация становится композицией функций, и, наконец, можно преобразовать в реальный список с помощью ($ [])
. Мне было интересно, какие операции можно эффективно поддерживать в списках различий. Например, эквивалент (:)
для списков различий:
\x l -> (x:) . l
Можно ли эффективно реализовать head
и tail
для списков различий? Вот очевидная реализация:
headTailDifList :: ([a] -> [a]) -> (a, [a] -> [a])
headTailDifList dl = (head l, ((tail l)++))
where
l = dl []
Для реальных списков \ l -> (head l, tail l)
выполняется за постоянное время. Что насчет этого headTailDifList
? Возможно, из-за ленивого вычисления будет вычислен только первый элемент l
?
headTailDifList
в постоянное время? Есть ли другая реализация с постоянным временем? Вот кандидат:
headTailDifList dl = (head (dl []), tail.dl)
Однако хвостовая часть не генерирует исключение, если dl
равно id
(пустой список различий).