Missing strict fields [GHC-95909]
When strict fields are declared for a datatype – either per-field with a strictness flag !, or for an entire type using the language extensions Strict/StrictData – all strict fields are strictly evaluated by constructors. Therefore, it is not possible to leave some strict fields unassigned, because they can’t be given a suspended bottom as a placeholder.
Therefore, it is required that all strict fields for a constructor are assigned on construction of the type.
If a non-strict field is missing, the warning GHC-20125 is emitted instead.
Examples
Missing strict field in record syntax
The instantiation of a strict field in a record is missing. In aFine, we can leave one field uninstantiated as it is not strict, and therefore is not evaluated until needed, due to lazy evaluation. However in aBad we cannot, as the field a is strict.
Error Message
MissingStrictField.hs:12:8: error: [GHC-95909]
• Constructor ‘A’ does not have the required strict field(s): a
• In the expression: A {b = 5}
In an equation for ‘aBad’: aBad = A {b = 5}
|
12 | aBad = A { b = 5 }
| ^^^^^^^^^^^
MissingStrictField.hs
module MissingStrictField where
data A = A
{ a :: !Bool
, b :: Int
}
aFine :: A
aFine = A { a = True }
aBad :: A
aBad = A { b = 5 }
module MissingStrictField where
data A = A
{ a :: !Bool
, b :: Int
}
aFine :: A
aFine = A { a = True }
aFixed :: A
aFixed = A { a = True, b = 5 }
All fields are strict if the StrictData language extension is enabled
When using the language extension {-# LANGUAGE Strict #-} or {-# LANGUAGE StrictData #-}, all fields are strict, even if we do not explicitly use the strictness flag !. Thus, we must instantiate all fields on construction.
Error Message
StrictExtension.hs:9:8: error: [GHC-95909]
• Constructor ‘A’ does not have the required strict field(s): b
• In the expression: A {a = True}
In an equation for ‘aBad’: aBad = A {a = True}
|
9 | aBad = A { a = True }
| ^^^^^^^^^^^^^^
StrictExtension.hs:12:12: error: [GHC-95909]
• Constructor ‘A’ does not have the required strict field(s): a
• In the expression: A {b = 5}
In an equation for ‘aAlsoBad’: aAlsoBad = A {b = 5}
|
12 | aAlsoBad = A { b = 5 }
| ^^^^^^^^^^^
StrictExtension.hs
{-# LANGUAGE Strict #-}
module StrictExtension where
data A = A
{ a :: Bool
, b :: Int
}
aBad :: A
aBad = A { a = True }
aAlsoBad :: A
aAlsoBad = A { b = 5 }
{-# LANGUAGE Strict #-}
module StrictExtension where
data A = A
{ a :: Bool
, b :: Int
}
aFixed :: A
aFixed = A { a = True, b = 5 }
aAlsoFixed :: A
aAlsoFixed = A { a = True, b = 5 }