Учите вас, 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(пустой список различий).

