
My tuppence: I feel like the main impetus for TDNR is the awkwardness of records, especially when there are multiple record types within a module (as there often are). Now, if one proceeds as one has to today, then one may find: data Foo = Foo { fooName :: String, fooValue :: Double } data Bar = Bar { barName :: String, barValue :: [String], barSubbars :: [Bar] } Let us, for sake of argument, ignore that perhaps fooName and barName represent the same semantic concept and these should all somehow be refactored. I suspect that the prime annoyance, the thing that makes us yearn for our old C/C++/Java/Python ways, is the tediousness of having to prefix all the field names with "foo" or "bar". Especially when the data type name is large, one ends up having to invent coding conventions one doesn't want to: data ExecutionTraceSummary = ExecutionTraceSummary { etsStart :: Time; ... } So imagine that we take the tedium out of typing all those prefixes by anointing some initial character, say the apostrophe, as a sort of name mangler: data Foo = Foo { 'name :: String, 'value :: Double } data Bar = Bar { 'name :: String, 'value :: [String], 'subbars :: [bar] } data ExecutionTraceSummary = ExecutionTraceSummary { 'start :: Time, ... } Now, to use them, perhaps we have to explicitly write the full form: showFoo :: Foo -> String showFoo f = Foo'name f ++ "(" ++ show (Foo'value f) ++ ")" We could allow a form of shortened local reference by allowing the full form to "flow through" type declarations: type ETS = ExecutionTraceSummary logExecutionTraceSummary :: ExecutionTraceSummary -> IO () logExecutionTraceSummary s = do putStr $ ETS'start s Mind you, I realize that apostrophe may not work here, and details haven't been worked out. [...that was the first pence, here comes the second...] If you buy any of that, then one could allow, in the manner pointed out by some (though in particular I'm thinking of David Menendez's example), that this construction could imply a type class and associated type. That is, the first appearance of 'name in a record implies this: class <C>'name a where type <R>'name a :: * 'name :: a -> <R>'name a and for each appearance of 'name :: X as a field of Foo: instance <C>'name Foo where type <R>'name Foo = X 'name = Foo'name (Here, <C> and <R> are some unwritable prefixes used by the compiler. It remains to be seen if these should be module scoped or program global.) So, in the case (repeated from above): data Foo = Foo { 'name :: String, 'value :: Double } data Bar = Bar { 'name :: String, 'value :: [String], 'subbars :: [Bar] } We get auto generated: class <C>'name a where type <R>'name a :: * 'name :: a -> <R>'name a class <C>'value a where type <R>'value a :: * 'value :: a -> <R>'value a class <C>'subbars a where type <R>'subbars a :: * 'subbars :: a -> <R>'subbars a instance <C>'name Foo where type <R>'name Foo = String 'name = Foo'name instance <C>'name Bar where type <R>'name Bar = String 'name = Bar'name instance <C>'value Foo where type <R>'value Foo = Double 'value = Foo'value instance <C>'value Bar where type <R>'value Bar = [String] 'value = Bar'value instance <C>'subbars Bar where type <R>'subbars Bar = [Bar] 'subbars = Bar'subbars *Now* one can write: showFoo :: Foo -> String showFoo f = 'name f ++ "(" ++ show ('value f) ++ ")" nameBoth :: Foo -> Bar -> String nameBoth f b = 'name f ++ " " ++ 'name b None of this requires any more type machinery than already exists with TypeFamilies. It perhaps suffer some of the prior objections to implying semantic equivalence (in say the 'value fields) where none exists. But, it is limited in scope to fields, and only when one uses the special naming sigil (apostrophe here). Of course, this approach would meld nicely with any better record/label system. For starters: class <C>'name a where type <R>'name a :: * 'name :: a -> <R>'name a ''name :: <R>'name a -> a -> a instance <C>'name Foo where type <R>'name Foo = String 'name = Foo'name ''name = \v x -> x { Foo'name = v } There now -- I feel like TNDR is placating the muscle memory in our fingers that wants to type "f.name" ... and I hope we find a solution to replacing the tedium of so many "fooName" fields, and perhaps solve the record update ugliness as well! - Mark Mark Lentczner http://www.ozonehouse.com/mark/ IRC: mtnviewmark