liveBook · Manning

Field selector

As explained in Learn Haskell by Example

A field selector is a function generated from a record field declaration that retrieves that field's value from a record.

A field selector is a function automatically generated from a record field declaration. It takes a record and returns that field’s value, giving record data both named access and lightweight documentation. section 7.1.1

Selectors in GHCi

For `data Record = Record { field1 :: Int, field2 :: String }`, GHC creates `field1 :: Record -> Int` and `field2 :: Record -> String`. Applying `field1` to `Record { field1 = 1, field2 = "" }` returns `1`. section 7.1.1

A selector shared by multiple constructors can safely retrieve a field when every constructor supplies it. A selector present in only some constructors is partial: applying it to another constructor is undefined and can raise a runtime exception. section 10.3.1

Use field selectors with these practical safeguards:

  • Choose distinctive field names, because generated selector functions can clash across records; prefixes such as `csvHeader` help avoid collisions. section 7.1.1
  • Compile with `-Wpartial-field` to detect accidental partial selectors, including those introduced during refactoring. section 10.3.1
  • Use `NoFieldSelectors` when a module should define explicit accessor functions instead of exposing dangerous automatically generated selectors. section 10.3.1
ghci> :{
ghci| data Record = Record
ghci|   { field1 :: Int,
ghci|     field2 :: String
ghci|   }
ghci| :}
ghci> :t field1
field1 :: Record -> Int
ghci> :t field2
field2 :: Record -> String
ghci> field1 (Record {field1 = 1, field2 = ""})
1

Inspect generated selector types and apply a selector to a constructed record. section 7.1.1

Listing 10.9 A function to apply an ADSR envelope to a signal
module Composition.Performance where

import Util.Types

data Event
  = Tone {freq :: Hz, start :: Seconds,
 duration :: Seconds}                                #1
  | Silence {start :: Seconds, duration :: Seconds}   #2
  deriving (Show)           #3

isTone :: Event -> Bool     #4
isTone Tone {} = True
isTone _ = False

isSilence :: Event -> Bool      #5
isSilence Silence {} = True
isSilence _ = False

end :: Event -> Seconds        #6
end e = start e + duration e

See selectors shared by `Tone` and `Silence`, alongside a partial `freq` selector. section 10.3.1

How Learn Haskell by Example covers it

How deep it goes
Explains generated selector types, constructor behavior, partiality, warnings, naming collisions, and explicit-accessor alternatives.
Examples
Demonstrates selectors with generic records, CSV contents, and music events containing shared or constructor-specific fields.
What it assumes
Assumes basic Haskell data declarations and constructors while demonstrating record syntax and selector behavior directly.
What you can do after
Diagnose/debug selector types, collisions, and partial-field failures, then replace unsafe access with explicit accessors.
How it connects
Connects record syntax with algebraic data types, partial functions, compiler warnings, and the NoFieldSelectors language extension.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Haskell by Example. The section links point to the parts of the book it draws on.