cd ..
), and the possibility to go downwards (cd subdirectory
). The zipper is the pointer to the current path. Behind the scenes the zippers are efficient when making (functional) changes to a data structure, where a new, slightly changed, data structure is returned from an edit operation (instead of making a change in the current data structure).
Example: Bidirectional list traversal
Many common data structures in computer science can be expressed as the structure generated by a few primitive constructor operations or observer operations. These include the structure of finite lists, which can be generated by two operations: *Empty
constructs an empty list,
* Cons(x, L)
constructs a list by prepending or concatenating value x
in front of list L
.
A list such as , 2, 3
The comma is a punctuation mark that appears in several variants in different languages. It has the same shape as an apostrophe or single closing quotation mark () in many typefaces, but it differs from them in being placed on the baseline o ...
/code> is therefore the declaration Cons(1, Cons(2, Cons(3, Empty)))
. It is possible to describe the location in such a list as the number of steps from the front of the list to the target location. More formally, a location in the list is the number of Cons
operations required to reconstruct the whole list from that particular location. For example, in Cons(1, Cons(2, Cons( X, Cons(4, Empty))))
a Cons(2, L)
and a Cons(1, L)
operation would be required to reconstruct the list relative to position X otherwise known as Cons( X, Cons(4, Empty))
. This recording together with the location is called a zipped representation of the list or a list-zipper.
To be clear, a location in the list is not just the number of Cons
operations, but also all of the other information about those Cons
; in this case, the values that must be reconnected. Here, these values may be conveniently represented in a separate list in the order of application from the target location. Specifically, from the context of "3" in the list , 2, 3, 4
The comma is a punctuation mark that appears in several variants in different languages. It has the same shape as an apostrophe or single closing quotation mark () in many typefaces, but it differs from them in being placed on the baseline (t ...
/code>, a recording (commonly referred to as a 'path') could be represented as , 1
The comma is a punctuation mark that appears in several variants in different languages. It has the same shape as an apostrophe or single closing quotation mark () in many typefaces, but it differs from them in being placed on the baseline (t ...
/code> where Cons(2, L)
is applied followed by (Cons 1, L)
to reconstitute the original list starting from , 4
The comma is a punctuation mark that appears in several variants in different languages. It has the same shape as an apostrophe or single closing quotation mark () in many typefaces, but it differs from them in being placed on the baseline ...
/code>.
A list-zipper always represents the entire data structure. However, this information is from the perspective of a specific location within that data structure. Consequently, a list-zipper is a pair consisting of both the location as a context or starting point, and a recording or path that permits reconstruction from that starting location. In particular, the list-zipper of , 2, 3, 4
The comma is a punctuation mark that appears in several variants in different languages. It has the same shape as an apostrophe or single closing quotation mark () in many typefaces, but it differs from them in being placed on the baseline (t ...
/code> at the location of "3" may be represented as (, 1
The comma is a punctuation mark that appears in several variants in different languages. It has the same shape as an apostrophe or single closing quotation mark () in many typefaces, but it differs from them in being placed on the baseline (t ...
, 4
The comma is a punctuation mark that appears in several variants in different languages. It has the same shape as an apostrophe or single closing quotation mark () in many typefaces, but it differs from them in being placed on the baseline ...
. Now, if "3" is changed to "10", then the list-zipper becomes (, 1
The comma is a punctuation mark that appears in several variants in different languages. It has the same shape as an apostrophe or single closing quotation mark () in many typefaces, but it differs from them in being placed on the baseline (t ...
0, 4
. The list may then be efficiently reconstructed: , 2, 10, 4/code> or other locations traversed to.
With the list represented this way, it is easy to define relatively efficient operations on immutable data structures such as Lists and Trees at arbitrary locations. In particular, applying the zipper transform to a tree makes it easy to insert or remove values at any particular location in the tree.
Contexts and differentiation
The type of a zipper's contexts can be constructed via a transformation
Transformation may refer to:
Science and mathematics
In biology and medicine
* Metamorphosis, the biological process of changing physical form after birth or hatching
* Malignant transformation, the process of cells becoming cancerous
* Trans ...
of the original type that is closely related to the derivative
In mathematics, the derivative of a function of a real variable measures the sensitivity to change of the function value (output value) with respect to a change in its argument (input value). Derivatives are a fundamental tool of calculus. F ...
of calculus
Calculus, originally called infinitesimal calculus or "the calculus of infinitesimals", is the mathematical study of continuous change, in the same way that geometry is the study of shape, and algebra is the study of generalizations of arithm ...
through decategorification. The recursive types that zippers are formed from can be viewed as the least fixed point of a unary type constructor of kind . For example, with a higher-order type constructor that constructs the least fixed point of its argument, an unlabeled binary tree can be represented as and an unlabeled list may take the form . Here, the notation of exponentiation, multiplication, and addition correspond to function types, product type
In programming languages and type theory, a product of ''types'' is another, compounded, type in a structure. The "operands" of the product are types, and the structure of a product type is determined by the fixed order of the operands in the prod ...
s, and sum type
In computer science, a tagged union, also called a variant, variant record, choice type, discriminated union, disjoint union, sum type or coproduct, is a data structure used to hold a value that could take on several different, but fixed, types. O ...
s respectively, whilst the natural numbers label the finite types; in this way, the type constructors resemble polynomial functions in .
The derivative of a type constructor can therefore be formed through this syntactic analogy: for the example of an unlabeled ternary tree, the derivative of its type constructor would be equivalent to , analogously to the use of the sum
Sum most commonly means the total of two or more numbers added together; see addition.
Sum can also refer to:
Mathematics
* Sum (category theory), the generic concept of summation in mathematics
* Sum, the result of summation, the additio ...
and power rules in differential calculus. The type of the contexts of a zipper over an original type is equivalent to the derivative of the type constructor applied to the original type, .
For illustration, consider the recursive data structure of a binary tree with nodes that are either sentinel nodes of type or contain a value of type :
The partial derivative of the type constructor can be computed to be
Thus, the type of the zipper's contexts is
As such, we find that the context of each non-sentinel child node in the labelled binary tree is a triple consisting of
* a boolean value
In mathematics and mathematical logic, Boolean algebra is a branch of algebra. It differs from elementary algebra in two ways. First, the values of the variables are the truth values ''true'' and ''false'', usually denoted 1 and 0, whereas in e ...
of type , expressing whether the current node is the left or right child of its parent node;
* a value of type , the label of the current node's parent; and
* the node's sibling of type , the subtree contained by the other branch of the current node's parent.
In general, a zipper for a tree of type consists of two parts: a list of contexts of type of the current node and each of its ancestors up until the root node, and the value of type that the current node contains.
Uses
The zipper is often used where there is some concept of focus or of moving around in some set of data, since its semantics reflect that of moving around but in a functional non-destructive manner.
The zipper has been used in
* Xmonad, to manage focus and placement of windows
Windows is a group of several proprietary graphical operating system families developed and marketed by Microsoft. Each family caters to a certain sector of the computing industry. For example, Windows NT for consumers, Windows Server for serv ...
* Huet's papers cover a structural editor A structure editor, also structured editor or projectional editor, is any document editor that is cognizant of the document's underlying structure. Structure editors can be used to edit hierarchical or marked up text, computer programs, diagrams, c ...
based on zippers and a theorem prover
* A filesystem (ZipperFS) written in Haskell offering "...transactional semantics; undo of any file and directory operation; snapshots; statically guaranteed the strongest, repeatable read, isolation mode for clients; pervasive copy-on-write for files and directories; built-in traversal facility; and just the right behavior for cyclic directory references."
* Clojure has extensive support for zippers.
Alternatives and extensions
Direct modification
In a non-purely-functional programming language, it may be more convenient to simply traverse the original data structure and modify it directly (perhaps after deep cloning it, to avoid affecting other code that might hold a reference to it).
Generic zipper
The generic zipper is a technique to achieve the same goal as the conventional zipper by capturing the state of the traversal in a continuation while visiting each node. (The Haskell code given in the reference uses generic programming to generate a traversal function for any data structure, but this is optional – any suitable traversal function can be used.)
However, the generic zipper involves inversion of control, so some uses of it require a state machine
A finite-state machine (FSM) or finite-state automaton (FSA, plural: ''automata''), finite automaton, or simply a state machine, is a mathematical model of computation. It is an abstract machine that can be in exactly one of a finite number o ...
(or equivalent) to keep track of what to do next.
References
Further reading
*
*
External links
{{Wikibooks, Haskell, Zippers
Zipper
Theseus and the Zipper
"Roll Your Own Window Manager: Tracking Focus with a Zipper"
Functional programming
Functional data structures