Q:

Why doesn't Haskell/GHC support record name overloading

I am a Haskell newbie. I have noticed that Haskell does not support record name overloading:
-- Records.hs

data Employee = Employee
  { firstName :: String
  , lastName :: String
  , ssn :: String
  } deriving (Show, Eq)

data Manager = Manager
  { firstName :: String
  , lastName :: String
  , ssn :: String
  , subordinates :: [Employee]
  } deriving (Show, Eq)

When I compile this I get:
[1 of 1] Compiling Main             ( Records.hs, Records.o )

Records.hs:10:5:
    Multiple declarations of `firstName'
    Declared at: Records.hs:4:5
                 Records.hs:10:5

Records.hs:11:5:
    Multiple declarations of `lastName'
    Declared at: Records.hs:5:5
                 Records.hs:11:5

Records.hs:12:5:
    Multiple declarations of `ssn'
    Declared at: Records.hs:6:5
                 Records.hs:12:5

Given the "strength" of the Haskell type system, it seems like it should be easy for the compiler to determine which field to access in
emp = Employee "Joe" "Smith" "111-22-3333"
man = Manager "Mary" "Jones" "333-22-1111" [emp]
firstName man
firstName emp

Is there some issue that I am not seeing. I know that the Haskell Report does not allow this, but why not?

A:

Historical reasons. There have been many competing designs for better record systems for Haskell -- so many in fact, that no consensus could be reached. Yet.

A:

The current record system is not very sophisticated. It's mostly some syntactic sugar for things you could do with boilerplate if there was no record syntax.
In particular, this:
data Employee = Employee
  { firstName :: String
  , lastName :: String
  , ssn :: String
  } deriving (Show, Eq)

generates (among other things) a function firstName :: Employee -> String.
If you also allow in the same module this type:
data Manager = Manager
  { firstName :: String
  , lastName :: String
  , ssn :: String
  , subordinates :: [Employee]
  } deriving (Show, Eq)

then what would be the type of the firstName function?
It would have to be two separate functions overloading the same name, which Haskell does not allow. Unless you imagine that this would implicitly generate a typeclass and make instances of it for everything with a field named firstName (gets messy in the general case, when the fields could have different types), then Haskell's current record system isn't going to be able to support multiple fields with the same name in the same module. Haskell doesn't even attempt to do any such thing at present.
It could, of course, be done better. But there are some tricky problems to solve, and essentially no one's come up with solutions to them that have convinced everyone that there is a most promising direction to move in yet.

A:

One option to avoid this is to put your data types in different modules and use qualified imports. In that way you can use the same field accessors on different data records and keep you code clean and more readable.
You can create one module for the employee, for example
module Model.Employee where

data Employee = Employee
  { firstName :: String
  , lastName :: String
  , ssn :: String
  } deriving (Show, Eq)

And one module for the Manager, for example:
module Model.Manager where

import Model.Employee (Employee)

data Manager = Manager
  { firstName :: String
  , lastName :: String
  , ssn :: String
  , subordinates :: [Employee]
  } deriving (Show, Eq)

And then wherever you want to use these two data types you can import them qualified and access them as follows:
import           Model.Employee (Employee)
import qualified Model.Employee as Employee
import           Model.Manager (Manager)
import qualified Model.Manager as Manager

emp = Employee "Joe" "Smith" "111-22-3333"
man = Manager "Mary" "Jones" "333-22-1111" [emp]

name1 = Manager.firstName man
name2 = Employee.firstName emp

Keep in mind that after all you are using two different data types and thus Manger.firstName is another function than Employee.firstName, even when you know that both data types represent a person and each person has a first name. But it is up to you how far you go to abstract data types, for example to create a Person data type from those "attribute collections" as well.

