Ответ 1
Цель здесь - не строгость, а упаковка этих элементов в структуру данных. Без строгости любой из этих трех аргументов конструктора мог указывать либо на структуру значений, распределенную по кучу, либо на выделенную кучу задержанную оценку. Со строгостью он может указывать только на структуру значений, распределенных по кучам. Со строгими и упакованными структурами можно сделать эти значения встроенными.
Поскольку каждое из этих трех значений является объектом размера указателя и в любом случае осуществляется доступ строго, принудительная строгая и упакованная структура сохраняет ссылки указателя при использовании этой структуры.
В более общем случае аннотация по строгости может помочь уменьшить утечки пространства. Рассмотрим такой случай:
data Foo = Foo Int
makeFoo :: ReallyBigDataStructure -> Foo
makeFoo x = Foo (computeSomething x)
Без аннотации строгости, если вы просто вызываете makeFoo
, он построит a Foo
, указывая на thunk, указывающий на ReallyBigDataStructure
, сохраняя его в памяти до тех пор, пока что-то не заставит thunk оценивать. Если мы вместо этого имеем
data Foo = Foo !Int
Это заставляет оценку computeSomething
действовать немедленно (ну, как только что-то заставляет makeFoo), что позволяет избежать ссылки на ReallyBigDataStructure
.
Обратите внимание, что это другой вариант использования, чем код байтовой строки; код bytestring сильно заставляет его параметры, что вряд ли приведет к утечке пространства. Вероятно, лучше всего интерпретировать код байтовой строки как чистую оптимизацию, чтобы избежать разметки указателя.