Как seq может оценить бесконечный список в Haskell?

Говорят, что функция Haskell seq принудительно вычисляет свой первый аргумент и возвращает второй. Он используется для добавления строгости к оценке выражений. Итак, как следующее может просто вернуть 5:

seq [1..] 5

Разве он не должен застревать в попытках построить бесконечный список?


person user3560270    schedule 27.02.2019    source источник
comment
seq (undefined, undefined) True не будет оценивать undefineds. То же самое для seq (undefined : undefined) True. Это связано с тем, что seq оценивает только достаточно, чтобы открыть первый конструктор, и не углубляется (см. также deepseq).   -  person chi    schedule 27.02.2019
comment
Списки на самом деле не бесконечны. Пропустив множество деталей, seq видит [1..] и оценивает его как 1 : [2..], затем останавливается. Хвост остается неоцененным до тех пор, пока он кому-то действительно не понадобится.   -  person chepner    schedule 27.02.2019


Ответы (1)


seq оценивается как слабая нормальная форма головы (WHNF), что, по сути, означает, что он оценивает один уровень конструкторов данных. В данном случае это означает, что принудительно вычисляется первая cons-ячейка (конструктор данных :).

У меня есть довольно длинный пост с объяснением деталей по адресу https://haskell.fpcomplete.com/tutorial/all-about-strictness

person Michael Snoyman    schedule 27.02.2019
comment
Имеет смысл. Я думаю, если вы действительно хотите, чтобы бесконечный список оценивался (я имею в виду застревание в бесконечной рекурсии), вы должны дать ему имя, а затем запросить его длину или что-то в этом роде. - person user3560270; 28.02.2019
comment
Или вы можете использовать что-то из пакета deepseq - person Michael Snoyman; 28.02.2019