Elixir needs a FIFO type?

That is still a zipper. :slight_smile:

A cursor style zipper is one that is used like:

iex(1)> new = fn -> {[],[]} end
#Function<20.52032458/0 in :erl_eval.expr/5>
iex(2)> move_left = fn {[l|x],r} -> {x,[l|r]} end
#Function<6.52032458/1 in :erl_eval.expr/5>
iex(3)> move_right = fn {l,[r|x]} -> {[r|l],x} end
#Function<6.52032458/1 in :erl_eval.expr/5>
iex(4)> get = fn {[l|_],_} -> l end
#Function<6.52032458/1 in :erl_eval.expr/5>
iex(5)> drop = fn {[_|l],r} -> {l,r} end
#Function<6.52032458/1 in :erl_eval.expr/5>
iex(6)> insert = fn({l,r},v) -> {[v|l],r} end
#Function<12.52032458/2 in :erl_eval.expr/5>
iex(7)> from_list = fn lst -> {[],lst} end
#Function<6.52032458/1 in :erl_eval.expr/5>
iex(8)> z = new.()
{[], []}
iex(9)> z |> insert.(1)
{[1], []}
iex(10)> z = z |> insert.(1)
{[1], []}
iex(11)> z = z |> insert.(2)
{[2, 1], []}
iex(12)> z |> get.()
2
iex(13)> z = z |> move_left.()
{[1], [2]}
iex(14)> z |> get.()
1
iex(15)> z = z |> drop.() |> move_right.()
{[2], []}
iex(16)> z |> get.()
2
iex(17)> z = from_list.([1,2,3,4,5,6])
{[], [1, 2, 3, 4, 5, 6]}
iex(18)> z |> move_right.() |> move_right.() |> drop.() |> move_right.() |> insert.(42) |> move_left.() |> move_left.() |> move_left.()
{[], [1, 3, 42, 4, 5, 6]}

And there are tons and tons and tons of more styles that zipper’s are useful for including not just lists but as you hinted at also maps and other things. A zipper can easily walk along every node in a deep map for example. :slight_smile: