An example from the HaskellNet library:
data MailboxInfo = MboxInfo { _mailbox :: MailboxName , _exists :: Integer , _recent :: Integer , _flags :: [Flag] , _permanentFlags :: [Flag] , _isWritable :: Bool , _isFlagWritable :: Bool , _uidNext :: UID , _uidValidity :: UID } deriving (Show, Eq)
Does the underscore in the field names mean something, if not to the compiler then at least according to Haskell convention?
Often an underscore character in Haskell code represents something we don't care about or don't know about – whether it's a wildcard, a hole, or a discarded result. Underscores appear both in types and in terms.
Records are an extension of sum algebraic data type that allow fields to be named: data StandardType = StandardType String Int Bool --standard way to create a product type data RecordType = RecordType -- the same product type with record syntax { aString :: String , aNumber :: Int , isTrue :: Bool }
By analogy to an underscore representing an irrelevant pattern, e.g. fst (x, _) = x
, an underscore prefix (on record fields or otherwise) is used to indicate that an identifier should be ignored by anyone reading the code, or perhaps ignored by the compiler for certain kinds of user interaction, even though it was given a name for some reason.
Note that this is not merely a convention, but based on something stated explicitly in the Haskell Report:
Underscore, "_", is treated as a lower-case letter, and can occur wherever a lower-case letter can. However, "_" all by itself is a reserved identifier, used as wild card in patterns. Compilers that offer warnings for unused identifiers are encouraged to suppress such warnings for identifiers beginning with underscore. This allows programmers to use "_foo" for a parameter that they expect to be unused.
One example would be definitions that are intended for use by Template Haskell, which then defines equivalent identifiers without the underscore, as in the common example of generating lenses based on record fields (which I'd guess is what your example is doing). In this case the identifiers are more input to TH than an actual definition; the code produced by TH may or may not actually use the underscore-prefixed identifiers.
Other than the above, though, an underscore prefix doesn't do anything differently from a regular lowercase identifier.
Template Haskell code sometimes looks for identifiers beginning with an underscore.
For instance, underscores are used to automate lens generation.
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