Lectures onType Theory
Chapter 81
Chapter 81Optional

Containers, Polynomial Functors, and Ornaments

Prerequisites. Direct starred prerequisites: none. No later core chapter depends on this route.

A list of length three contains three elements. Its description code in chapter 80 records how the list is constructed, but it does not isolate the choice “length three” from the three places where elements occur. Make that separation first. Take the natural number 3 as the shape and Fin(3) as its set of positions. A list over a type X is then a pair (n,f):n:NFin(n)X. The function f fills every position of the chosen shape with an element of X. This factorization is semantic: it tells us which choices determine the layout and which choices merely fill that layout.

Shapes and positions

Definition 81.1 — Container and extension

A container C is a pair (S,P) consisting of a type of shapes S:Ui and a family of position types P:SUi. Its extension at X:Ui is CX:=s:SP(s)X. For u:CX, write shape(u) for its first component and contents(u) for its second component.

The list container is CList:=(N,λn.Fin(n)). The element (3,λi.lookup(xs,i)) represents a three-element list xs. The empty shape has no positions: CListX(0,λi.rec0(i)). Here i:Fin(0), so empty elimination defines the contents map. The shape is not the stored data. Replacing X by another type changes the possible contents but leaves N and every Fin(n) fixed.

Definition 81.2 — Action on contents

For h:XY, define cmapC(h,(s,f)):=(s,λp.h(f(p))):CY.

For the list shape 3, the map with h(n)=n+10 calculates as cmapCList(λn.n+10,(3,[2,4,8]))(3,[12,14,18]). Only the position labels have been abbreviated by list notation; the calculation is pointwise application to Fin(3).

Proposition 81.3 — Container action laws

Let C be a container, let f:XY and g:YZ, and let u:CX. Then cmapC(λx.x,u)=u,cmapC(λx.g(f(x)),u)=cmapC(g,cmapC(f,u)). These are pointwise equalities at u; no function extensionality is used.

Proof of Proposition 81.3 — Container action laws

Proof. Write u(s,h). The first components on both sides are s. At a position p:P(s), the two contents calculations are respectively h(p)=h(p),g(f(h(p)))=g(f(h(p))). Sigma congruence with these pointwise paths gives the two stated equalities. ◻

Exercise 81.1

★☆☆ Let CBin:=(1,λ_.Fin(2)) represent one binary node layer. Give the shape and contents map of a node with child labels a,b:X, and calculate its image under h:XY. Explain why this container represents one binary layer, not a complete binary tree.

Maps that preserve layouts

A polymorphic layout transformation cannot inspect an X-element. It may choose a target shape from the source shape, then say where each target position obtains its source element. The direction of that second map is the first important variance calculation in the chapter.

Definition 81.4 — Container morphism

Let C=(S,P) and D=(T,Q). A container morphism m:CD consists of mS:ST,mP:s:SQ(mS(s))P(s). Its extension at X is mX((s,f)):=(mS(s),λq.f(mP(s,q))).

The position map runs from target positions to source positions because a target contents request must be answered from the given source contents. A map in the other direction could discard source positions, but it would not say how to fill a newly created target position.

Reverse on length-indexed lists is the morphism mS(n):=n,mP(n,i):=n1i with truncated natural subtraction interpreted inside Fin(n). At shape 3, mX((3,[x0,x1,x2]))(3,[x2,x1,x0]). This is the calculation used by Abbott, Altenkirch, and Ghani when they introduce container morphisms [AAG05].

Definition 81.5 — Identity and composition

The identity morphism has (idC)S(s):=s,(idC)P(s,p):=p. For m:CD and n:DE, define nm:CE by (nm)S(s):=nS(mS(s)),(nm)P(s,r):=mP(s,nP(mS(s),r)).

The laws follow by beta computation. More importantly, extension respects composition. For u(s,f), nmX(u)=(nS(mS(s)),λr.f(mP(s,nP(mS(s),r))))=definition81.4nX(mX(u)). The source paper proves that, in its extensional setting, container morphisms correspond fully and faithfully to natural transformations between container extensions. We use only the displayed direction: a container morphism gives the polymorphic map mX. The converse requires the source’s extensional equality and parametric/naturality interface; it is not a theorem of T0 merely because the two types look alike.

Exercise 81.2

★★☆ Define a container morphism representing list tail with target shape n1 using truncated subtraction. Give its position map, then calculate the extension at shapes 0 and 3. State why a morphism that always produces a nonempty target from the empty source shape cannot exist.

Polynomial operations

Containers calculate like polynomials because a shape chooses a monomial and its positions count occurrences of the variable. This is an equation about extensions, not permission to use subtraction or division on arbitrary types.

Definition 81.6 — Container sum and product

For C=(S,P) and D=(T,Q), define C+D:=(S+T,λu.case(u;s.P(s);t.Q(t))),C×D:=(S×T,λ(s,t).P(s)+Q(t)). The constant container at A is (A,λa.0), and the identity container is (1,λ_.1).

For the product, a value has a shape pair and a contents map on a coproduct of positions. Splitting that map gives one C-contents map and one D-contents map: C×DX:=s:St:T(P(s)+Q(t))X(s:SP(s)X)×(t:TQ(t)X). The equivalence sends h to its restrictions along inl and inr; the inverse performs case analysis. The sum calculation instead yields C+DXCX+DX.

Definition 81.7 — Composition of containers

For C=(S,P) and D=(T,Q), define CD by SCD:=s:SP(s)T,PCD(s,k):=p:P(s)Q(k(p)).

A composite shape first chooses an outer shape s, then one inner shape at each outer position. A composite position chooses an outer position p and then an inner position in k(p). Reassociating Sigma types gives CDXC(DX). For binary trees, composing the one-layer container with itself distinguishes the outer branching choice from the branching choices at its children. A single flattened count would lose that tree shape.

Exercise 81.3

★★☆ Let F(X)=1+A×X and G(X)=X×X. Express both as containers. Use definition 81.6, definition 81.7 to calculate containers for F(G(X)) and G(F(X)). Exhibit one shape on which their position types have different cardinalities.

Algebras and coalgebras under explicit hypotheses

The expression F(X)=1+A×X has many fixed points. Finite lists and possibly infinite lists are selected by universal properties, not by the equation XF(X) alone.

Definition 81.8 — Initial algebra and final coalgebra

Let F act on types and maps. An F-algebra is a pair (A,α) with α:F(A)A. An algebra morphism h:(A,α)(B,β) is a map h:AB satisfying h(α(u))=β(F(h)(u))(u:F(A)). An initial algebra is an algebra (μF,in) for which every (A,α) has exactly one algebra morphism from (μF,in).

Dually, an F-coalgebra is (A,γ) with γ:AF(A). A final coalgebra (νF,out) receives exactly one coalgebra morphism from every F-coalgebra.

Theorem 81.9 — Conditional fold and unfold laws

Let C be a container. If the extension C has an initial algebra (μC,in), then every α:CAA determines a unique foldα:μCA satisfying foldα(in(u))=α(cmapC(foldα,u)). If C has a final coalgebra (νC,out), then every γ:ACA determines a unique unfoldγ:AνC satisfying out(unfoldγ(a))=cmapC(unfoldγ,γ(a)).

Proof of Theorem 81.9 — Conditional fold and unfold laws

Proof. The first equation is exactly the commuting condition for the unique algebra morphism from the initial algebra to (A,α). The second is the commuting condition for the unique coalgebra morphism from (A,γ) to the final coalgebra. Existence and uniqueness are hypotheses in the two universal properties; this proof does not construct W-types or M-types. ◻

For CA representing 1+A×X, an assumed initial algebra gives finite lists and its fold equation. An assumed final coalgebra gives possibly infinite lists and its unfold equation. These are different selections of a solution to the same shape-position equation.

Remark 81.10 — Representation boundary

The container representation theorem is conditional on its semantic signature. The source works in extensional Martin–Löf type theory with disjoint coproducts, W-types, and a witness distinguishing the two Boolean constructors; its coinductive representation additionally reduces M-types to that setting [AAG05]. No such extensionality or M-type principle is added to T0 here. Hence theorem 81.9 states existence hypotheses explicitly.

Indexed containers

A vector layer must know both the index of each recursive child and the index of the result. A unary container has only one ambient type X, so it cannot record this flow of indices.

Definition 81.11 — Indexed container and extension

Let I,J:Ui. An indexed container from I to J consists of S:JUi,P:j:JS(j)Ui,n:j:Js:S(j)P(j,s)I. For X:IUi, its extension is the J-family S,P,n(X)(j):=s:S(j)p:P(j,s)X(n(j,s,p)). The map n assigns a source index to each recursive position.

For vector layers over A, take I=J=N. At result index 0, there is one nil shape with no recursive positions. At result index suc(k), a cons shape stores an A-element, has one recursive position, and sends that position to k. Its extension therefore calculates to CVec(A)X(0)1,CVec(A)X(suc(k))A×X(k). These are the two fibers of the vector description in chapter 80; they have been interpreted semantically, not identified definitionally with the description code.

The indexed source proves initiality of its indexed W-type construction and a normal-form result for strictly positive families. Proposition 5.2 gives the initial algebra calculation, including the commuting square and uniqueness proof, while the final comparison records that the reduction to W-types uses extensional propositional equality [AGH^+15]. We therefore import only the following bounded statement.

Theorem 81.12 — Indexed-container representation, source signature

In the extensional type theory of Altenkirch, Ghani, Hancock, McBride, and Morris, with the displayed indexed W/M-type and equality assumptions, every strictly positive family in their frozen grammar has an indexed-container normal form. Its inductive fixed point is initial; its coinductive fixed point is final when the required M-type exists.

Proof of Theorem 81.12 — Indexed-container representation, source signature

Imported proof. This imported theorem does not turn every endofamily operator into a container. It applies only to the source grammar and assumptions, and it does not transfer initiality or finality to the syntactic description universe of chapter 80 without an interpretation theorem. The imported construction and its initiality calculation are Proposition 5.2 and the normal-form development on pp. 24 and 39 of [AGH^+15]. ◻

Exercise 81.4

★★☆ Write all three components (S,P,n) of the vector-layer indexed container. For u:CVec(A)X(suc(k)), expand the type of its unique recursive child. Then change n so that the child is assigned index suc(k) and identify the lost descent invariant.

Derivatives are one-hole contexts

Consider a product X×X. Removing one occurrence of X leaves either a hole on the left with one stored right element, or a hole on the right with one stored left element. Thus its one-hole contexts have type X+X. The ordinary derivative (X2)=2X predicts the same two cases.

Definition 81.13 — Derivative of regular polynomial codes

For the regular grammar generated by constants K, the variable X, sums, and products, define K:=0,X:=1,(F+G):=F+G,(F×G):=(F×G)+(F×G). A value of F(X) is a one-hole F-shape whose other positions are filled with elements of X.

Proposition 81.14 — Plugging one hole

For every regular polynomial code F, there is a map plugF:F(X)×XF(X) defined by recursion on F.

Proof of Proposition 81.14 — Plugging one hole

Proof. The constant case has empty domain. For X, the unique context is and plugX(,x):=x. A sum context remembers its injection and uses the induction hypothesis in that branch. A product context is either inl(c,g):(F(X))×G(X)orinr(f,d):F(X)×G(X). Define plugF×G(inl(c,g),x):=(plugF(c,x),g), and define the right case by (f,plugG(d,x)). These clauses cover the regular grammar. ◻

The list equation L(X)=1+A×X describes one layer, while a complete list is its least fixed point. A one-hole context in a complete list is a prefix and a suffix: the hole is the focused element between them. For [a,b,c] focused at b, use ([a],[c]). Plugging b gives [a,b,c]. McBride derives this regular calculation directly [McB01]; the later container theory proves the sum, product, and chain laws for decidable containers [AAGM03].

Theorem 81.15 — Derivative laws at the decidable-container boundary

For decidable containers F and G in the source calculus, (F+G)F+G,(F×G)(F×G)+(F×G), and the source chain rule identifies (FG)(FG)×G.

Proof of Theorem 81.15 — Derivative laws at the decidable-container boundary

Imported proof. The decidability hypothesis selects the distinguished position needed by the container derivative. Dropping it does not leave the published construction available. The theorem asserts equivalences in the stated container setting; it does not define negative polynomial operations on arbitrary types. The displayed laws are the sum, product, and chain laws on pp. 12–13 of [AAGM03]. ◻

Exercise 81.5

★★☆ For T(X)=A+X×X, calculate T(X). List the two one-hole contexts of a binary node fork(l,r) and calculate plugging in each case. Verify the product rule by naming which sibling is stored.

Ornaments refine structure

Vectors do not merely pair lists with a length proof. Their constructors carry exactly the index information forced by list length. The relation is directed: a vector forgets to a list, while an arbitrary list does not become a vector at a preselected length.

Definition 81.16 — Ornament and forgetful map

Fix an index reorganization r:JI and an indexed description D:IDesci(I). An ornament O of D over r consists of a refined code family |O|:JDesci(J) and, for every family X:IUi, a layer map forgetLayerO:[[|O|(j)]](Xr)[[D(r(j))]](X) natural in X. More exactly, for every family map f:XY and layer u:[[|O|(j)]](Xr), mapD(r(j))(f,forgetLayerO,X(u))=forgetLayerO,Y(map|O|(j)(fr,u)). The transformation is cartesian: the induced map [[|O|(j)]](Xr)[[|O|(j)]](Yr)×[[D(r(j))]](Y)[[D(r(j))]](X) is an equivalence. This pullback condition preserves constructor choices and recursive positions. Folding the layer map gives forgetO:Mu(|O|)(j)Mu(D)(r(j)).

Cartesian layer transformations can insert stored Sigma data, delete data determined by a refined index, and refine recursive indices. These are constructions of ornaments, not permissions that replace the definition. The semantic presentation is the cartesian-morphism characterization of the description-ornament grammar of Dagand and McBride [DM14]; it is not arbitrary subtyping.

Take the natural-number description 1+X. Inserting an A-element at every successor gives lists over A; forgetting all inserted elements gives list length. Algebraically ornament that list description by its length algebra. The fiber at n is Vec(A,n), and the forgetful map is forgetVec:Vec(A,n)List(A).

Definition 81.17 — Algebraic ornament

Let D be a description and α:[[D]](X)X an algebra. The algebraic ornament of D by α refines each t:Mu(D) by the result of the fold foldα(t). Its fiber at x:X is equivalent, in the source signature, to t:Mu(D)IdX(foldα(t),x).

For the list-length algebra this gives the vector fiber. The source construction replaces the redundant pair “list plus proof of length” by a constructor-indexed representation, but retains the coherence theorem [DM14]: length(forgetVec(xs))=n(xs:Vec(A,n)).

Proposition 81.18 — Transported map coherence

Let f:AB, n:N, and xs:Vec(A,n). Then forgetVec(vmap(f,xs))=map(f,forgetVec(xs)).

Proof of Proposition 81.18 — Transported map coherence

Proof. Induct on xs. At vnil, both sides compute to nil. In the successor case, write xsvcons(a,ys). The induction hypothesis gives forgetVec(vmap(f,ys))=map(f,forgetVec(ys)). Apply congruence for cons(f(a),): forgetVec(vmap(f,vcons(a,ys)))cons(f(a),forgetVec(vmap(f,ys)))=IHcons(f(a),map(f,forgetVec(ys)))map(f,forgetVec(vcons(a,ys))). ◻

The proof transports one program and its defining equation from lists to vectors. It does not state that every list program has a unique lifting. Functional ornaments determine a coherence relation for a selected lifting; the remaining proof obligations depend on that function ornament [DM14].

Exercise 81.6

★★☆ Prove forgetVec(vappend(xs,ys))=append(forgetVec(xs),forgetVec(ys)) for inputs xs:Vec(A,m),ys:Vec(A,n). State the result index of vappend(xs,ys) and identify where it is erased.

Exercise 81.7

★★☆ Suppose a proposed “ornament” maps a binary-node layer to a leaf layer while retaining only the left subtree. Show that it has no position map of the form required by definition 81.4 for a forgetful map preserving all recursive positions. Show that the induced naturality square is not a pullback, so the cartesian clause of definition 81.16 fails.

What survives in ML

Dependent indices are not required to generate useful lifted code, but without them the index law moves out of the type and into a relation. Williams and Rémy’s ML example relates Peano naturals to lists by RA(0,nil):=1,RA(suc(n),cons(a,xs)):=RA(n,xs). The relation is many-valued because the list head a:A is new data. Their lift of addition therefore needs a patch telling the generated successor case where to obtain the head. After that patch, the generated term is list append [WR18].

Proposition 81.19 — The append lifting preserves the ML ornament

If RA(m,xs) and RA(n,ys), then RA(m+n,append(xs,ys)).

Proof of Proposition 81.19 — The append lifting preserves the ML ornament

Proof. Induct on the witness of RA(m,xs). In the zero/nil case, both 0+n and append(nil,ys) compute to the second input, so the second relation witness is the result. In the successor/cons case, write msuc(k) and xscons(a,zs). The induction hypothesis gives RA(k+n,append(zs,ys)). Applying the successor/cons clause yields RA(suc(k+n),cons(a,append(zs,ys))), which is the goal after the defining equations for addition and append. ◻

The source lifting pipeline first abstracts the original ML term to a generic term, instantiates that term at the requested ornament relation, performs meta-reduction, and simplifies the result. Theorem 7.6 proves correctness only when the instruction is appropriate in the source judgment; at the strictly positive first-order instance, its logical relation specializes to the proposition above [WR18]. This is not the dependent vector theorem: ordinary ML accepts lists of every length, and the relation rather than the type carries the length invariant.

Exercise 81.8

★★☆ Let mapList(f) be the lifting of the identity-on-length function from the natural/list ornament to lists over B, using f:AB as the patch for inserted heads. Prove RA(n,xs)RB(n,mapList(f,xs)). State the ML type of the lifted function and the dependent fact that the type does not express.

Bibliographic note

The shape-position presentation and its morphisms follow the container development of Abbott, Altenkirch, and Ghani and its expanded treatment with McBride [AAG05]. Indexed containers and their W/M-type boundary are taken from the 2015 journal development [AGH^+15]. The derivative calculation follows the primary container papers and McBride’s regular one-hole account [AAGM03, McB01]. The list/vector refinement and transport boundary follow Dagand and McBride [DM14]. The separate ML lifting comparison follows Williams and Rémy [WR18].

Suggested first pass.

None of these problems is a prerequisite for a later chapter. Begin with exercise 81.9, exercise 81.12.

Exercise 81.9

★★☆ For the list container, compose reverse with itself using definition 81.5. Calculate both components of the composite and prove that its extension at every X is pointwise equal to the identity.

Exercise 81.10

★★★ Calculate ((1+A×X)×(1+B×X)). Interpret every summand as a one-hole context and write the complete plugging function. Give one input for each summand.

Exercise 81.11

★★☆ Build a two-element example showing that the equation X1+A×X does not by itself select finite lists. Then name the exact universal property that distinguishes the finite solution from a final coalgebra solution.

Exercise 81.12

★★★ Practical project.container-ornament-calculator Implement in Kappa the finite list container at shapes at most four, its reverse container morphism, the list-to-vector forgetful calculation, and a one-hole list zipper. Maintain the invariant that every contents array has exactly as many entries as its shape and that plugging increases the stored prefix-plus-suffix size by one. On the named input [2,4,8], print the shape, the reversed contents, the result of replacing the focused value 4 by 5, and the forgotten vector contents. Reject a mutated vector with declared length 2 and three elements with the witness shape-content-mismatch. The acceptance test passes exactly when the four calculations and the rejection witness match these values.

Search the book

Type to search the local edition.