
I added my evaluation of the module-based approach to existing records, but on second thoughts it's maybe inappropriate, so I'll post it here. I saw that some people commented on the reddit discussion that the solution is to put your types in separate modules but it doesn't seem that anyone has tried to do this on a large scale. I tried it (and some other record paradigms including Has), but I don't think it scales. Here's why… Suppose I have 112 hand-crafted data types in my project (e.g. see attachment 51369.txt[1]), this creates a lot of conflicts in field names and constructor names. For example: {{{ data Comment = Comment { commentId :: CommentId , commentContent :: Content , commentReviewId :: ReviewId , commentSubmissionId :: SubmissionId , commentConferenceId :: ConferenceId , commentDate :: ISODate , commentReviewerNumber :: Int } deriving (Show) }}} This is a real type in my project. It has fields like “id”, “content”, “reviewId”, “submissionId”, “date”. There are seven other data types that have a field name “submissionId”. There are 15 with “conferenceId”. There are 7 with “content”. And so on. This is just to demonstrate that field clashes ''do'' occur ''a lot'' in a nontrivial project. It also demonstrates that if you propose to put each of these 112 types into a separate module, you are having a laugh. I tried this around the 20 type mark and it was, apart from being very slow at compiling, ''very'' tedious to work with. Creating and editing these modules was a distracting and pointless chore. It ''also'' demonstrated, to me, that qualified imports are horrible when used on a large scale. It happened all the time, that'd I'd import, say, 10 different data types all qualified. Typing map (Foo.id . BarMu.thisField) and foo Bar.Zot{x=1,y=2} becomes tedious and distracting, especially having to add every type module when I want to use a type. And when records use other types in other modules, you have ''a lot'' of redundancy. With the prefixing paradigm I'd write fooId and barMuThisField, which is about as tedious but there is at least less . confusion and no need to make a load of modules and import lines. Perhaps local modules would solve half of this problem. Still have to write “Bar.mu bar” rather than “mu bar”, but it'd be an improvement. I also have 21 Enum types which often conflict. I end up having to include the name of the type in the constructor, or rewording it awkwardly. I guess I should put these all in separate modules and import qualified, too. Tedious, though. At least in this case languages like C# and Java also require that you type EnumName.EnumValue, so c‘est la vie. [1]: http://hackage.haskell.org/trac/ghc/attachment/wiki/Records/51369.txt