
My application is a server written in Haskell that receives uploads of structured data and persists them to disk and redistributes them on demand, kind of a persistent messaging middleware. Anyway, I started out using Haskell record syntax for everything, hit the usual problems with name clashes and ended up with field label names that looked like hungarian notation, everything looked a bit grimy and verbose etc,etc. As an experiment I got rid of the labels, and anywhere I had a product type that had more than one field of the same type (usually these were primitive types I hadn't bothered to create wrapper types for, e.g. Price and Quantity were both Double), I took that to be a "code smell" and created types that more accurately captured the use of the field's value in the program domain. Next I created a class Extractor to provide a standard way to pull individual fields from the product type: class Extract a b where extract :: a -> b e.g.: instance Extract Upload ClientID where extract (Upload c _ _ _ _ _) = c instance Extract Upload RecordPeriod where extract (Upload _ p _ _ _ _) = p So I can pass an Upload to extract and thanks to type inference it will usually be unambiguous, and I can annotate with a type signature to make it clearer what field I'm extracting as I see fit. I was missing record update syntax so I added a class to make it easier to do that: class Transform a b where transform :: a -> (b->b) -> a e.g.: instance Transform Upload ClientID where transform (Upload c p ab ar lr br) f = (Upload (f c) p ab ar lr br) i.e. take a function that updates a contained value and apply it to the appropriate field in an otherwise identical copy of the original. Apart from the verbosity of the instance declarations for every field I was pleased with the result, and the imposed discipline of giving each field a distinct type significantly improved the codebase. My questions are: 1) I presume this approach has been explored and probably there is a well thought through library of helper classes and functions already out there, can someone please point me to it? 2) I don't know much about Haskell generics, but for product types in which all contained values are distinct types, it should be possible to automatically derive instances of Extract, since there's never ambiguity as to which field you want from a container if you've specified the type of value you want, is this possible, and if so does it already exist? 3) In type theory, are product types consisting of distinct member types considered special in any way? i.e. does the concept have a name and what special properties do they have? Thanks for your help. T