[Haskell-cafe] Shadowing record field names

Li-yao Xia lysxia at gmail.com
Sat Dec 23 14:41:29 UTC 2017


I don't think "authorL" hurts readability. It just seems the logical 
choice if "author" is already taken.

Have you seen generic-lens? The lens for the "author" field is  (field 
@"author") so there is some added noise compared to "authorL", but it 
can be used as a TH-free alternative to makeClassy.

type Field name a = forall s. HasField name s s a a => Lens s s a a

authorL :: Field "author" Author
authorL = field @"author"

Cheers,
Li-yao

On 12/23/2017 08:36 AM, ☂Josh Chia (謝任中) wrote:
> 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
> 
> 
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
> 


More information about the Haskell-Cafe mailing list