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.