Прагма может быть немного уродливой, но она позволяет избежать больше уродства в других местах.Когда производительность критична, программистам часто приходится выбирать конкретную форму для конструктора данных.Предположим, у меня есть
data Point = Point Int Int
data Segment = Segment Point Point
. Это логично, но имеет ряд дополнительных косвенных указаний: один Segment
состоит из семи объектов кучи.Если я работаю с большим количеством сегментов, это очень плохо.
Я мог бы раздавить эту квартиру вручную:
data Segment = Segment Int# Int# Int# Int#
, но теперь я потерял тот факт, что числа представляюточков, и все, что я делаю с сегментом, должно включать довольно неудобные и странные операции без коробки.
К счастью, есть лучший способ:
-- The small strict Int fields will be unpacked by default
-- with any reasonably recent GHC version.
data Point = Point !Int !Int
data Segment = Segment {-# UNPACK #-} !Point {-# UNPACK #-} !Point
Это все равно дает мне один объект кучи насегмент, но я могу использовать Point
s и Int
s и (как правило) полагаться на компилятор, распаковывая все красиво.