Skip to content

Can't re-export duplicate field names from identical constructor names

This is a new ticket to track an issue explained by @adamgundry in a prior (closed) ticket. That is, the following code leads to the following error. The error is still present as of GHC 9.8. It seems like an artificial limitation and it would be great if it could be lifted. This is particularly annoying if we want to create a custom Prelude. It makes it impossible to create a custom Prelude containing two different fields with the same name, if their constructors also share the same name.

{-# LANGUAGE DuplicateRecordFields #-}
module A where
  data S = C { foo :: Int }

{-# LANGUAGE DuplicateRecordFields #-}
module B where
  data T = C { foo :: Int }

{-# LANGUAGE DuplicateRecordFields #-}
module C (S(foo), T(foo)) where
  import A (S(..))
  import B (T(..))
    Conflicting exports for ‘foo’:
       ‘S(foo)’ exports ‘foo’
         imported from ‘A’ at C.hs:5:28-32
         (and originally defined at A.hs:3:16-18)
       ‘T(foo)’ exports ‘foo’
         imported from ‘B’ at C.hs:6:28-32
         (and originally defined at B.hs:5:14-16)

It's also an interesting puzzle to try to imagine the implementation details that allow both foos to be used within the same module but not re-exported from the same module! I haven't been able to work it out ...

EDIT: Ah, I think I have an explanation: in a given module, duplicate field names are disambiguated by the module they were imported from plus the constructor name.

Edited by Tom Ellis
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information