Cyclical data structures in Elixir?

Zippers can be used to implement a two-way navigational list. The example in the article doesn’t support cycle, but it should be very easy to extend it by adding a clause which matches on the empty list in the second element.

The idea is to keep a tuple in the shape of {visited::[any], remaining::[any]}. So for example, in a tuple {[3, 2, 1], [4, 5, 6]} you’re currently at the element 4, while previously visited 1, 2, 3 (in that order). The next operation will move 4 to the top of the first list, so you’ll get {[4, 3, 2, 1], [5, 6]}. If after the move the second list is empty, then you just reverse the first list, and return {[], reversed_first_list}. So next({[5, 4, 3, 2, 1}, [6]) will return {[], [1, 2, 3, 4, 5, 6]}, and you’re back at the start.

You can take the similar approach to move in the opposite direction. The prev operation pops the head off the first list and pushes it at the top of the second list, unless the first list is empty, in which case you need to keep the last element of the second list, reversing all others into the first list.

Supporting insert and delete is as easy as pushing/popping to/from the top of the second list.