Если вы не храните большое вычисление в полях Int и Float, значительные накладные расходы могут возникать из множества тривиальных вычислений, создаваемых в thunks. Например, если вы повторно добавляете 1 к ленивому полю Float в типе данных, он будет использовать все больше и больше памяти, пока вы на самом деле не заставите поле, вычислив его.
Часто вы хотите сохранить дорогостоящие вычисления в поле. Но если вы знаете, что раньше не делаете ничего подобного, вы можете пометить поле строгое, и не нужно вручную добавлять seq
всюду, чтобы получить желаемую эффективность.
В качестве дополнительного бонуса, когда данный флаг -funbox-strict-fields
GHC распакует жесткие поля типов данных непосредственно в самом тип данных, что возможно, так как он знает, что они всегда будут оценены, и, таким образом, нет преобразователя не должен выделяться; в этом случае значение Bar будет содержать машинные слова, содержащие Int и Float, непосредственно внутри значения Bar в памяти, вместо того, чтобы содержать два указателя на thunks, которые содержат данные.
Laziness - очень полезная вещь, но некоторое время она просто мешает и мешает вычислению, особенно для небольших полей, которые всегда смотрятся (и, следовательно, вынуждены), или которые часто изменяются, но никогда очень дорогостоящие вычисления. Строгие поля помогают преодолеть эти проблемы, не изменяя все виды использования типа данных.
Является ли это более распространенным явлением, чем ленивые поля или нет, зависит от типа кода, который вы читаете; вы вряд ли увидите, что какие-либо функциональные древовидные структуры широко используют строгие поля, например, потому что они очень выигрывают от лени.
Допустим, у вас есть AST с конструктором для инфиксные операций:
data Exp = Infix Op Exp Exp
| ...
data Op = Add | Subtract | Multiply | Divide
Вы не хотели бы сделать Exp
поля строги, как применение политики, как это будет означать, что вся AST оценивается когда вы смотрите на узел верхнего уровня, что явно не то, что вы хотите извлечь из лени. Однако поле Op
никогда не будет содержать дорогостоящие вычисления, которые вы хотите отложить до более поздней даты, а накладные расходы на thunk для каждого инфиксного оператора могут стать дорогими, если у вас действительно глубоко вложенные деревья синтаксического анализа. Итак, для конструктора infix вы должны сделать поле Op
строгим, но оставьте полями Exp
ленивыми.
Только одноконструкторы могут быть распакованы.
Как АСТ не должно быть столь же строгим? – Lanbo
Я расширил свой ответ с некоторой разработки с использованием АСТ в качестве примера. – ehird