I suppose that, in my personal experience, I just haven't written a lot of Haskell code that used multiple similar record types in the same namespace.
I don't have any evidence for this, but I feel like it's often a bit of a code smell when this problem crops up. It seems like it frequently happens when programmers used to OOP are trying to shoehorn an object oriented design into a language which is just fundamentally not object oriented. I'm not saying that that's the only situation in which this problem arises, nor that the complaint isn't a legitimate one, regardless. There is no question that the situation could be improved. And perhaps I've just gotten lucky so far and haven't come across a scenario in which this really causes difficulties.
That said, there are always ways to work around the issue. I will make no claims of elegance here, but it's really not that much trouble. For one, you can define the different record types in separate modules, and then import them qualified. That's easy enough to do; it's just annoying to have to use multiple files.
Alternatively, you can keep the ugly prefixes on the record field names, but then use a type class to elide them away everywhere you refer to them. This technique only works when the similarly-named fields have the same type in each record, unless you use fundeps or associated types to attach additional type information to your class. For example:
{-# LANGUAGE TypeFamilies #-}
data Foo = Foo {foo_field1 :: Char, foo_field2 :: String}
data Bar = Bar {bar_field1 :: Int, bar_field2 :: String}
class MyRecord a where type Field1Type a
field1 :: a -> Field1Type a
field2 :: a -> String
instance MyRecord Foo where type Field1Type Foo = Char
field1 = foo_field1
field2 = foo_field2
instance MyRecord Bar where type Field1Type Bar = Int
field1 = bar_field1
field2 = bar_field2
You could even use Template Haskell to automatically generate the instances so you don't have to tediously type them out yourself, especially handy for records with a large number of fields.
So I'm not claiming that there's no problem to be solved. I would be happy to see a real solution to this that doesn't require any workarounds. I just don't think it's a big enough issue to keep me from using a language which is, in nearly all other respects, awesome. :)
I don't have any evidence for this, but I feel like it's often a bit of a code smell when this problem crops up. It seems like it frequently happens when programmers used to OOP are trying to shoehorn an object oriented design into a language which is just fundamentally not object oriented. I'm not saying that that's the only situation in which this problem arises, nor that the complaint isn't a legitimate one, regardless. There is no question that the situation could be improved. And perhaps I've just gotten lucky so far and haven't come across a scenario in which this really causes difficulties.
That said, there are always ways to work around the issue. I will make no claims of elegance here, but it's really not that much trouble. For one, you can define the different record types in separate modules, and then import them qualified. That's easy enough to do; it's just annoying to have to use multiple files.
Alternatively, you can keep the ugly prefixes on the record field names, but then use a type class to elide them away everywhere you refer to them. This technique only works when the similarly-named fields have the same type in each record, unless you use fundeps or associated types to attach additional type information to your class. For example:
You could even use Template Haskell to automatically generate the instances so you don't have to tediously type them out yourself, especially handy for records with a large number of fields.So I'm not claiming that there's no problem to be solved. I would be happy to see a real solution to this that doesn't require any workarounds. I just don't think it's a big enough issue to keep me from using a language which is, in nearly all other respects, awesome. :)