А вот такой список в хаскеле используется чуть для другого:
Он там вместо итератора за счёт ленивости языка. Т.к. когда ты делаешь Cons там, то из-за ленивости там реально будет что-то вроде:
Cons(Lazy(head), Lazy(tail)), где, что head, что tail будут высчитаны, только при явном их использовании.
Отсюда у них есть набор хороших свойств, который позволяет переписывать операции со списками так, что в реальности создаваться они тупо не будут.
Т.е. большинство библиотченых операций с ними в хаскеле выражены через unfold и fold таких списков, и при этом можно пользоваться тем, что fold от unfold можно вычислить без создания списка, чем и пользуется стандартная библиотека через специально описанные rewrite rules для компилятора.
Гм, а разве компилятор не уберёт вычисление всего списка? Просто в силу ленивости вычисления