The motivation for records is given clearly in the Haskell tutorial
"Learn You a Haskell For Great Good!"

Suppose you've been tasked with creating a data type that describes a
person.  The info that we want to store about that person is: first
name, last name, age, height, phone number, and favorite ice-cream
flavor.  Without records you might consider either of the two alternatives:

> type Person1 = (String, String, Int, Float, String, String)
> data Person2 = Person2 String String Int Float String String deriving Show 
> guy1 = ("Buddy", "Finklestein", 43, 184.2, "526-2928", "Chocolate")
> guy2 = Person2 "Buddy" "Finklestein" 43 184.2 "526-2928" "Chocolate"

Some obvious difficulties ensue; primarily we must define a
multitude of selector functions in each case.  For example:

> age1 :: Person1 -> Int
> age1 (_,_,n,_,_,_) = n
> age2 :: Person2 -> Int
> age2 (Person2 _ _ n _ _ _) = n

Records can make this easier.

> data Person = Person { firstName :: String  
>                      , lastName :: String  
>                      , age :: Int  
>                      , height :: Float  
>                      , phoneNumber :: String  
>                      , flavor :: String  
>                      } deriving Show 

(NB. The only constructor has the same name as the data type.)
Now we have all the selectors without writing any additional code.

< ghci> :t flavor  
< flavor :: Person -> String  
< ghci> :t firstName  
< firstName :: Person -> String 

The labels make the code more understandable. In addition we don't
have to remember the positional order of the data structure:

> guy = Person {firstName="Buddy", lastName="Finklestein",
>    flavor="Chocolate", height=184.2, phoneNumber="526-2928", age=43}

We take up another example -- this one from a blog of Luis Diego
Falls.  But first we need this auxiliary definition in what follows:

> data Color = Black | White
>    deriving Show

Records are immutable data structures consisting of labeled fields.
For example, here's a small definition of a data type to store the
information of a theme:

> data Theme = Theme {
>                      keywordsColor :: Color,
>                      backgroundColor :: Color,
>                      fontSize :: Int,
>                      operatorsColor :: Color,
>                      literalsColor :: Color
>                 }
>         deriving Show

(Often the only constructor has the same name as the data type.)
An instance of this record can be created by invoking the constructor:

> baseTheme = Theme { keywordsColor = Black,
>                     backgroundColor = White,
>                     fontSize = 10,
>                     operatorsColor = Black,
>                     literalsColor = Black }


A new record may be created out of an existing record.  Say that we
want to create a dark theme which is the same as the base theme, but
with colors inverted.

> darkTheme = baseTheme {
>                         keywordsColor = White,
>                         backgroundColor = Black,
>                         operatorsColor = White,
>                         literalsColor = White
>                       } 

Here we're saying that we want a copy of baseTheme with keywordsColor,
backgroundColor, operatorsColor and literalsColor changed to another value.
Fields cannot be updated in place like records in imperative languages.

As with other data structures we can use pattern matching to extract
parts of the record. For example, say that we want to define a function
to increase the current font size of a theme:

> increaseFontSize :: Int -> Theme -> Theme
> increaseFontSize amount (theme @ Theme{fontSize=currentFontSize}) =
>    theme {fontSize = currentFontSize + amount} 

We can use this function definition as follows:

increaseFontSize 5 baseTheme
Theme {keywordsColor = Black, backgroundColor = White,
            fontSize = 15, operatorsColor = Black, literalsColor = Black }
