Marcus

Marcus

Another zipper implementation base on the paper Functional pearl: the zipper by Gérard Huet. Inspired by the erlang zipper and the great sourceror project.

ZipperEx provides functions to handle and traverse tree data structures.

To create a zipper you can use the ZipperEx.Zipable protocol or create a
module.

Creating a zipper module:

Imagine we have a tree structure based on a tuple with an integer value and a
list of cildren. The leafs of the tree are also integers. A tree may then look
like the following:

{1, [2, {3, [4, 5]}, 6, {7, [0]}]}

To handle this tree we create the following module:

defmodule My.Zipper do
  use ZipperEx

  @impl ZipperEx
  def branch?(item) do
    case item do
      {_, [_ | _]} -> true
      _else -> false
    end
  end

  @impl ZipperEx
  def children({_, children}), do: children

  @impl ZipperEx
  def make_node({value, _children}, children), do: {value, children}

  def make_node(value, children), do: {value, children}
end

For use ZipperEx we have to implement the callbacks c:branch?/1,
c:children/1 and c:make_node/2.

The My.Zipper module contains all functions the ZipperEx also
provides.

We can now use My.Zipper.

iex> alias My.Zipper
iex> zipper = Zipper.new({1, [2, {3, [4, 5]}, 6, {7, [0]}]})
#ZipperEx<{1, [2, {3, [4, 5]}, 6, {7, [0]}]}>
iex> zipper = Zipper.down(zipper)
#ZipperEx<2>
iex> zipper = Zipper.right(zipper)
#ZipperEx<{3, [4, 5]}>
iex> zipper |> Zipper.remove() |> Zipper.root()
{1, [2, 6, {7, [0]}]}

Using the ZipperEx.Zipable protocol

Similar to the module example the protocol needs implementations for
ZipperEx.Zipable.branch?/1, ZipperEx.Zipable.children/1 and
ZipperEx.Zipable.make_node/2.

defmodule My.TreeNode do
  @moduledoc false

  defstruct value: nil, children: []

  def new({value, children}) do
    struct!(__MODULE__, value: value, children: Enum.map(children, &new/1))
  end

  def new(value), do: struct!(__MODULE__, value: value)

  defimpl ZipperEx.Zipable do
    def branch?(%{children: [_ | _]}), do: true

    def branch?(_node), do: false

    def children(%{children: children}), do: children

    def make_node(node, children), do: %{node | children: children}
  end

  defimpl Inspect do
    def inspect(node, _opts), do: "#TreeNode<#{node.value}, #{inspect(node.children)}>"
  end
end

My.TreeNode can then be used as follows:

iex> alias My.TreeNode
iex> tree = TreeNode.new({1, [2, {3, [4, 5]}]})
iex> zipper = ZipperEx.new(tree)
iex> ZipperEx.down(zipper)
#ZipperEx<#TreeNode<2, []>>
iex> zipper |> ZipperEx.down() |> ZipperEx.rightmost()
#ZipperEx<#TreeNode<3, [#TreeNode<4, []>, #TreeNode<5, []>]>>
iex> {_zipper, acc} = ZipperEx.traverse(zipper, [], fn z, acc ->
...>   node = ZipperEx.node(z)
...>   {z, [node.value | acc]}
...> end)
iex> acc
[5, 4, 3, 2, 1]

Where Next? Top

Trending in Announcing Top

type1fool
WebAuthnLiveComponent WebAuthnComponents See this post about renaming the package. Passwordless authentication for Phoenix LiveView app...
New
GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
woylie
I released Doggo, a collection of unstyled Phoenix components. https://github.com/woylie/doggo Features Unstyled Phoenix components....
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
ahamez
Hi everyone, I’ve been working on this protobuf library for 3 years. We use it in the company I work for, EasyMile, to communicate with ...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
kip
I’ll shortly be launching Text, a nascent text analysis library. Current functionality In this early version (not ready for prime time) ...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New
bartblast
Hey folks, I just published a post about Hologram’s funding and where the project goes next - the short version: Curiosum as Main Spons...
New
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews