Да, вы правы.
Оперативно, в случае 1, переменная v
привязана к thunk, неоцененному выражению, которое становится все больше и больше, пока print
не вызовет свою оценку.Объем памяти не постоянен.
В случае 2 переменная v
всегда связана с вычисленным числом.Рекурсия выполняется в постоянном пространстве.
Кстати, идиоматично писать seq v' f' xs v'
как
v' `seq` f' xs v'
или, используя $!
f' xs $! v'
Другой распространенный выбор - использовать шаблон взрыва и забыть seq
f' [] !v = print v -- base case
f' (x:xs) !v = f' xs v'
where v' = v + g x
Взрывы !
гарантируют, что v
требуется немедленно, поэтому, даже если это thunk, он оценивается перед продолжением,Это также обеспечивает постоянный объем памяти.
В качестве инструмента профилирования для строгости вы можете попробовать Debug.Trace.trace
, который будет печатать отладочное сообщение всякий раз, когда требуется какой-либо блок.Это не должно использоваться для общего вывода, но для общей отладки вполне подойдет.