Подтвердить что ты не робот

Обозначение диапазона Haskell для создания списка. Неожиданный результат

Я наткнулся на упражнение в одной из моих лекций, которые оставили меня в замешательстве на выходе из [2, 2.. 2]. Почему при входе в [2, 2.. 2] он генерирует "бесконечный" список с 2-мя.

То, как я понял, обозначение было то, что первым элементом является начальная граница, вторая - "пробел" между числами, а последний - конец списка, другими словами, останавливается при достижении этого числа.

Если мои рассуждения верны, почему выражение [2, 2.. 2] не выводится [2]?.


Я думал, что Haskell может оценить это так:

  • При печати первого элемента в списке он равен последний, поэтому остановка.
  • Или, если первый элемент не проверен на "внешнюю" привязку, тогда выход будет [2, 2], потому что при добавлении нуля к предыдущему номеру (в случае с началом 2) мы имели бы дошел до конца и, следовательно, остановился.

Я, очевидно, не правильно понимаю работу обозначений, так как Haskell оценивает выражение?

4b9b3361

Ответ 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.