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