I would like to implement a Doubly Connected Edge List data structure for use in Haskell. This data structure is used to manage the topology of an arrangement of lines in a plane, and contains structures for faces, edges, and vertices.
It seems to me like a good interface to this data structure would be as a type Arrangement, with functions like
overlay :: Arrangement -> Arrangement -> Arrangement
but the usual implementation relies heavily on references (for example each face has references to the adjacent edges).
It seems to me that the ideal way for this to work would be similar to the way mutable and immutable arrays do: the internals of the Arrangement data structure are implemented as functional data structures, but the operations that mutate arrangements "unfreeze" them to create new mutable instances within a monad (ideally using COW magic to make things efficient).
So my questions are:
(1) is there a way to freeze and unfreeze a small heap like there is for arrays? (2) if not, is there a better approach?
Not that the safe versions of
freezeandthawmake complete copies of the array, so aren't necessarily that efficient. Of course, making a complete copy of an array of refs is arguably an optimization over making a complete copy of a structure through walking it and recursively pulling things ou ofMVars, etc.Another approach to take would be something similar to that of
Repa-- represent operations over your structure algebraically, and write arunfunction that optimizes, fuses, and then executes all in one pass. Arguably this is a more functional design. (You can use unsafe operations under the covers even, to make reification happen on-demand rather than explicitly).