Обозначение диапазона Haskell для создания списка. Неожиданный результат
Я наткнулся на упражнение в одной из моих лекций, которые оставили меня в замешательстве на выходе из [2, 2.. 2]. Почему при входе в [2, 2.. 2] он генерирует "бесконечный" список с 2-мя.
То, как я понял, обозначение было то, что первым элементом является начальная граница, вторая - "пробел" между числами, а последний - конец списка, другими словами, останавливается при достижении этого числа.
Если мои рассуждения верны, почему выражение [2, 2.. 2] не выводится [2]?.
Я думал, что Haskell может оценить это так:
- При печати первого элемента
в списке он равен
последний, поэтому остановка.
- Или, если первый элемент не проверен на "внешнюю" привязку, тогда выход будет [2, 2], потому что при добавлении нуля к предыдущему номеру (в случае с началом 2) мы имели бы дошел до конца и, следовательно, остановился.
Я, очевидно, не правильно понимаю работу обозначений, так как Haskell оценивает выражение?
Ответы
Ответ 1
Обозначение предназначено для имитации обычного способа написания простых математических последовательностей последовательностей. Второй элемент - это не шаг, а фактически фактический второй элемент списка. Остальное линейно экстраполировано оттуда. Примеры:
[1,2..10] = [1,2,3,4,5,6,7,8,9,10]
[1,3..10] = [1,3,5,7,9]
[4,3..0] = [4,3,2,1,0]
[0,5..] = [0,5,10,15,20,25,30,35... -- infinite
[1,1..] = [1,1,1,1,1,1,1,1,1,1,1... -- infinite
Причина [2,2..2]
бесконечна, потому что ни одно значение списка никогда не будет больше, чем правая конечная точка, которая является условием завершения. Если вы хотите, чтобы шаг был 2, вы должны написать [2,4..2]
, который дает ожидаемый результат [2]
. (Поэтому я предполагаю, что это не фактический второй элемент списка во всех случаях, но вы видите логику)
Ответ 2
В основном потому, что стандарт указывает это. [e1, e2 .. e3]
desugars до enumFromThenTo e1 e2 e3
В разделе в разделе 6.3.4 в отчете Haskell'98 говорится:
Последовательность enumFromThenTo e1 e2 e3 - это список [e1, e1 + i, e1 + 2i,... e3], где приращение я является e2-e1. Если приращение положительное или нулевое, список заканчивается, когда следующий элемент будет больше, чем e3; список пуст, если e1 > e3. Если приращение отрицательное, список заканчивается, когда следующий элемент будет меньше, чем e3; список пуст, если e1 < e3.
Следующий элемент никогда не больше 2.