
Hello! 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. I want to gradually decorate these labels with more and more information. For nodes, it may be the number of outgoing edges or the position of the node in space. For edges, it may be whether an edge is directed or not, or whether it was added by some computation, like say transitive closure. 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. It would be nonsense if a node was said to be undirected or for an edge to be declared a leaf. I would also like not to provide all the labels ahead of time, but rather define whatever labels are needed in the module that defines the corresponding decorating functions. An example for the sort of things I have in mind: class Suitable label type | label → type … data Topology = Root | Internal | Leaf instance Suitable Topology NodeLabels detectTopology ∷ graph someNodeLabels whateverEdgeLabels → graph (someNodeLabels + Topology) whateverEdgeLabels I looked into `extensible` and `vinyl`. * `extensible` does not seem to fit because it defines field labels to be type level strings, making them all interchangeable — there is no way to enforce the distinction between labels suitable for nodes and for edges. * `vinyl` seems to be more flexible and low level, but this also means that it is steeper to learn. The example from the repository uses an enumeration to define a set of labels for a type of records, and this means that the set of labels cannot be extended across modules — this is a problem for me and I am not sure if it can be solved within `vinyl`. What should I do?