I'm using Clojure's zippers to implement what I thought wouldn't be particularly challenging but it seems I may be missing something.
Essentially what I want to do is, given some data structure as a list, e.g. (1 (2 3) 4)), I want to be able to associate some meta-data against a particular loc so that I can make decisions about that loc given a different loc.
For example, using seq-zip from the zipper library, when I hit the loc for 2 in the above list I want to associate some arbitrary data with that loc, then when I hit loc 3 I want to examine that data (using something like clojure.zip/prev to get there) and then make a decision based on whether or not that particular loc had some data associated with it.
However it doesn't seem particularly straight forward, I've tried assoc'ing some data against the loc, but after using clojure.zip/next, the data is still present in the loc map, which isn't what I wanted.
Unfortunately because the node values I'm working with can be numbers, I can't simply supplement the node values themselves with meta-data, unless I we're to box the values in some sort of wrapper, but this seems rather ugly, any ideas?
There is only one meaningful
locobject at a time: it is your "cursor" into the zipped data structure. Therefore, you can only store metadata on it globally. Since your nodes have no room for metadata themselves, you can either wrap the nodes (e.g., just globally wrap everything in a map as Alan Thompson suggests), or else store in the loc a sufficiently powerful metadata map to contain everything you'd want to know about all nodes. For example, loc's metadata could contain a map whose keys are paths in the zipper and whose values are decorations for the node at that path. It's not ideal, because if you edit the structure of your tree, the metadata will be left dangling. But if you do a structure-preserving traversal of the tree, this could work. Personally, I like Alan's idea better. Represent data as data.