<div dir="ltr">Quite often, I need to use record types like this:<div><br></div><div>data Whole1 = Whole1 { part :: Part, ... }</div><div>data Whole2 = Whole2 { part :: Part, ... }<br></div><div><br></div><div>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.</div><div><br></div><div>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).</div><div><br></div><div>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:</div><div><br></div><div>findAuthorLibraries :: Author -> [Library] -> [Library]</div><div>findAuthorLibraries author libraries = ...</div><div><br></div><div>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.</div><div><br></div><div>Maybe I should use Lens.Control.TH.makeClassy and then define:</div><div><br></div><div>findAuthorLibraries :: HasAuthor a => a -> [Library] -> [Library]</div><div>findAuthorLibraries hasAuthor libraries = ...<br></div><div><br></div><div>But that may be making my function more complicated and general than I want, affecting readability, simplicity, compilation time and maybe even performance.</div><div><br></div><div>In summary, I find that there are ways around the problem but they really affect readability.</div><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>What do people do to address this problem? Any recommendations or best practices?</div><div><br></div><div>Josh</div></div>