[Haskell-cafe] Shadowing record field names

☂Josh Chia (謝任中) joshchia at gmail.com
Sat Dec 23 13:36:07 UTC 2017


Quite often, I need to use record types like this:

data Whole1 = Whole1 { part :: Part, ... }
data Whole2 = Whole2 { part :: Part, ... }

Where Whole1 & Whole2 are types of things that have a Part and some other
things. E.g. a Book has an Author, a Title, etc and so does an Article.

The problem is that I'm not actually allowed to use the same name
(author/part) in two different record types. Some people use lens to solve
this. You can have a lens called 'author' for dealing with the Author in
both Book and Article (e.g. using makeClassy).

That's fine, but there's yet another problem. Let's say I have a function
that takes an Author and a [Library] and returns all the Libraries that
have Books or Articles matching the Author. So:

findAuthorLibraries :: Author -> [Library] -> [Library]
findAuthorLibraries author libraries = ...

But I already have a lens called 'author' and ghc will complain about
shadowing. So, to avoid shadowing, should I use 'theAuthor' instead of
'author' for the function argument? Or, should I name the lens
'authorLens', 'authorL' or 'lAuthor' instead of 'author'? Prefixing with
'the' is quite unreadable because whether or not an argument has that
prefix depends on whether there's a lens with a conflicting name so it adds
noise to the code. Adding a 'Lens' prefix to the 'author' lens also seems
quite an overbearing eyesore because for consistency I would have to use
the prefix for all my field-accessing lenses.

Maybe I should use Lens.Control.TH.makeClassy and then define:

findAuthorLibraries :: HasAuthor a => a -> [Library] -> [Library]
findAuthorLibraries hasAuthor libraries = ...

But that may be making my function more complicated and general than I
want, affecting readability, simplicity, compilation time and maybe even
performance.

In summary, I find that there are ways around the problem but they really
affect readability.

I could also disable the warning about shadowing but that seems pretty
dangerous. It may be OK to disable the warning for the specific cases where
a function argument shadows something from the topmost scope, but GHC does
not allow such selective disabling of that warning.

In a code base that deals mainly with concrete business logic, this problem
probably crops up more than in a code base that deals mainly with more
abstract things.

What do people do to address this problem? Any recommendations or best
practices?

Josh
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20171223/c922c953/attachment.html>


More information about the Haskell-Cafe mailing list