Found some old notes on Haskell’s record syntax.

From the Haskell report we have,

Translation: A field label f introduces a selector function defined as:

C1, Cn are all the constructors of the datatype containing a field labeled with f, pij is y when f labels the j th component of Ci, or _ otherwise, and ei is y when some field in Ci has a label of f or undefined otherwise.

In other word, for a label f and value x, pattern matching on x will imply some Ci, and if some pij has label f, then pij and ei are y, else pij is _ and ei is undefined.

Synonyms: f is a “selector function”, or a “field label”.

Take for example Reader. Then we have the following.

notes from irc

04:24 <parsnip> no exercise sets to help practice haskell fields?
04:24 <parsnip> s/fields/records/
04:26 <ertes-w> parsnip: i can come up with a few exercises, if you want me to
04:28 <parsnip> only if you agree they should exist, i can simply read the docs, continue researching, etc.
04:28 <parsnip> and whenever you have the time, no rush
04:29 <ertes-w> parsnip: i do agree, so here is exercise 1 (the later
ones are going to build on it): define a type called Person and two
functions (name :: Person -> String), (age :: Integer)
04:29 <ertes-w> parsnip: however, you must only use a single definition
04:33 <parsnip> hmm, not age :: Person -> Integer?
04:33 <ertes-w> parsnip: yes, sorry
05:08 <ertes-w> parsnip: then here goes exercise 2: write a function
(mapName :: (String -> String) -> Person -> Person) under the
following constraints: 1. the word "age" does not appear in the
implementation, 2. the function would work unchanged even if the
fields of Person were flipped
05:12 <ertes-w> parsnip: (and of course the function should do what its name suggests)
05:14 <ertes-w> parsnip: but just to be safe, here is a third
constraint: the function should satisfy the following equations for
all 'f', 'n', 'p': name (mapName f p) = f (name p); age (mapName f p)
= age p
05:15 <ertes-w> (scratch 'n')

This second exercise did well to have me notice the difference between the syntax in haskell report’s sections 3.15.2 and 3.15.3. That is, their C { bs } vs e { bs }.

In other words, my first try was

but then rereading I realized I needed

In summary, we can encounter field selection, f x, construction with field labels, C { bs }, and updates using field labels, e { bs }.

00:14 <ertes-w> parsnip: great, that was exactly the point of the
exercise, so here goes exercise 3: generalise (Person :: *) to
(Person :: * -> * -> *), change 'age' to (age :: Person a b -> a), and
add a field (info :: Person a b -> b), leave the 'name' field
unchanged
00:15 <ertes-w> parsnip: adjust the type signature of 'mapName' to
account for that change
00:15 <ertes-w> parsnip: (the implementation shouldn't need to change)