
I have a situation that I think is a good case to apply extensible records to. I have two kinds of entities that are both extensible but in different ways — I would like to make sure their fields are not mixed. At the same time, I want to be able to extend the sets of fields across several modules. Is it possible and is it practical? My case is that I have a type for graphs that is a bifunctor — in node labels and edge labels. So, I need to be able to add more and more fields to labels, but in such a way that it is impossible to assign an unsuitable field.
If your graph is already a bifunctor, why not use a disctinct label or node type in each use case/module? That certainly fits the requirement of not mixing fields. Then you could go the old-fashioned way of type classes, e.g. class HasTopology label where topology :: label -> Topology instance HasTopology Topology where topology = id instance HasTopology label => HasTopology (label,moreInfo) where topology = topology.fst Or for updateable fields, use a Lens Topology. This is a lot of boilerplate, I admit, but you have fine-grained control over what your types have in common. Nested pairs are type- level polymorphic lists and with the right type classes can be used as such, if the list of types is known at compile-time. It is similar to what mtl does with the MonadFoo classes. Olaf