Given a datatype
data Foo = Foo { one :: Int, two :: String } deriving (Show)
An incomplete expression passes typechecking -- e.g.
foo :: Foo
foo = Foo { one = 5 }
main = print foo
Typechecks (emitting a warning about the incomplete record), then (obviously) crashes when the expression is encountered. Why does it pass? Without record syntax it doesn't (i.e. bar = Foo 5 :: Foo).
The Haskell 2010 report says in section 3.15.2 Construction Using Field Labels
A constructor with labeled fields may be used to construct a value in which the components are specified by name rather than by position. Unlike the braces used in declaration lists, these are not subject to layout; the { and } characters must be explicit. (This is also true of field updates and field patterns.) Construction using field labels is subject to the following constraints: [...]
Fields not mentioned are initialized to ⊥.
A compile-time error occurs when any strict fields (fields whose declared types are prefixed by !) are omitted during construction.
So it's part of the language specification and a compiler must accept the code. All fields are initialized, just some are initialised with undefined.
foo = Foo{ one = 5 }
is equivalent to
foo = Foo 5 undefined
A nice compiler will warn you about it if you ask it to. If you want an error, make the fields strict.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With