records
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)