I've got some composite types that I use at various points in a data structure (roughly node-ish and edge-ish). In many cases, I'll want to specia-case the types, though, for performance (even though, from an abstract point of view, they'll be doing the same job as the originals). The thing is that some of the fields will be irrelevant for some of the instances, so I might as well have specific types without those fields. For the ones where all the mutable fields are irrelevant, I would generally make the resulting special case immutable. In some of my cases this can lead to a drastic compactification of the data structure, and I can handle various conditionals by dispatching to the right function, etc. (The latter I could do with the proper type parameters too, of course.)
I've gone back and forth between generating the types (metaprogramming) and hand-coding some cases I know make sense – and both solutions leave a little to be desired. The hand-coding works well enough, except that I have an exponential number of potential types, and I'm not sure exactly which will be needed, so it would be better to (1) reduce the code duplication, and (2) generate the types on demand. However, the metaprogramming can become a bit messy – or at least less readable. (I'd like the code to be usable as an explanation of the algorithm/data structure I'm designing, so I don't want to obscure it behind my optimization.) One idea I've implemented a simple version of is to start with a "template type" which has all the fields, and then have a factory function that generates new types where all but the specified fields have been eliminated. It works, but it's a bit messy – and there's the issue of identifying the right type without too much overhead when the objects are created. Any Julianic way of doing this sort of thing – or something similar? (Or just some general ideas, for that matter?)
