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