[Haskell-cafe] Not too extensible records?

Ignat Insarov kindaro at gmail.com
Sat Feb 27 11:27:15 UTC 2021


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?


More information about the Haskell-Cafe mailing list