Lectures onType Theory
Chapter 84
Chapter 84Optional

Mendler Recursion, Nested Datatypes, and Mixed Variance

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

For an ordinary fixed point μF, a fold first maps its recursive function over one F-layer and then applies an algebra. That recipe assumes a map operation for F. It fails twice in the developments of this chapter. A nested datatype changes its parameter at a recursive occurrence, so one endofunctor F:UiUi is not enough. A mixed-variance operator may place its argument to the left of an arrow, so it has no covariant map at all. Mendler’s repair does not give the recursive layer a map. It gives the algebra a polymorphic recursive-call argument whose abstract domain prevents the algebra from applying recursion to a value it has constructed itself.

The recursive call is abstract

First freeze the rank-zero interface. Let F:UiUi be a type operator and assume a carrier μMF:Ui with constructor inFM:F(μMF)μMF. This is a selected Mendler fixed-point interface, not the ordinary strictly positive fixed point of chapter 80. No destructor is available.

The complete interface appears in the fixed order formation, introduction, elimination, computation:

ΓF:UiUi
ΓμMF:Ui
Mendler-form
Γu:F(μMF)
ΓinFM(u):μMF
Mendler-intro
ΓA:UiΓϕ:R:Ui(RA)F(R)A
ΓmfoldF(ϕ):μMFA
Mendler-elim
Γϕ:R:Ui(RA)F(R)AΓu:F(μMF)
mfoldF(ϕ)(inFM(u))ϕ(μMF,mfoldF(ϕ),u):A
Mendler-β

The interface deliberately contains no positivity premise and no F-action. Its normalization claim is therefore not inherited from the strictly positive fixed points of chapter 80; it is the selected metatheorem stated below.

Definition 84.1 — Mendler algebra

For A:Ui, a Mendler algebra is a term of type MAlg(F,A):=R:Ui(RA)F(R)A. Its first argument R is abstract. Its second argument is the only recursive call available while processing a layer F(R).

Definition 84.2 — Mendler iteration

For ϕ:MAlg(F,A), the iterator mfoldF(ϕ):μMFA satisfies the computation equation mfoldF(ϕ)(inFM(u))ϕ(μMF,mfoldF(ϕ),u). The rule is available only at the selected fixed-point signature.

No mapF occurs in (84.1). This is the first gain: the algebra itself decides where its R-values occur. The universal quantifier is the second gain. A definition of ϕ must work for every R, so it cannot assume R=μMF, inspect an R-value, or pass a freshly constructed μMF value to the recursive call RA.

For the list base operator FA(R):=1+(A×R), define ϕlength(R,rec,inl()):=0,ϕlength(R,rec,inr((a,r))):=suc(rec(r)). Then mfoldFA(ϕlength)(inFAM(inr(a,inFAM(inl))))(84.1)suc(mfoldFA(ϕlength)(inFAM(inl)))(84.1)suc(0).

Proposition 84.3 — Ordinary folds are Mendler folds

Suppose F has an action mapF and let α:F(A)A. Put ϕα(R,rec,u):=α(mapF(rec,u)). Then ϕα:MAlg(F,A), and its Mendler equation is the ordinary fold equation.

Proof of Proposition 84.3 — Ordinary folds are Mendler folds

Proof. For arbitrary R, the action sends u:F(R) and rec:RA to mapF(rec,u):F(A). Applying α gives A. Substitution in (84.1) yields mfoldF(ϕα)(inFM(u))α(mapF(mfoldF(ϕα),u)), the ordinary fold equation. ◻

The converse does not hold for an arbitrary F: a Mendler algebra can use the known constructors of F(R) without supplying a map for all functions RR. This is why the presentation remains meaningful at selected mixed-variance operators.

Exercise 84.1

★☆☆ For f:AB, define a Mendler algebra with result μMFB that maps every list element by f. Expand (84.1) at nil and cons, including the type of the recursive argument in the cons clause.

Why the abstraction blocks self-application

If negative recursive occurrences are admitted together with an unrestricted destructor, termination fails without any value-level recursive definition. Consider the equations T(T1),C:(T1)T,out:T(T1). Define w(x):=out(x)(x) and ω:=C(w). Then w(ω)out(C(w))ww(ω). The cycle is generated by the negative occurrence of T in T1.

Now retain only the Mendler constructor for FT(R):=R1. To recover the destructor, one would need a Mendler algebra with result μMFT1: ϕ:R:Ui(R(μMFT1))(R1)(μMFT1). Given f:R1, the attempted clause returns f. Its required type is μMFT1. The two domains are R and μMFT, and the universal R cannot be converted to the fixed point. The self-application program therefore fails at the exact place where it would export the negative embedded function.

Lemma 84.4 — Abstract-domain confinement

In a parametric model of definition 84.1, a Mendler algebra cannot apply its recursive argument rec:RA to a value whose type is not obtained as an R-component of its input u:F(R).

Proof of Lemma 84.4 — Abstract-domain confinement

Proof. Relate an arbitrary R to a one-point copy R by a relation that contains exactly the R-components selected from u. Parametricity of ϕ:R:Ui(RA)F(R)A requires its result to be invariant under this relation. A call rec(r) is related only when r belongs to the selected R-components. A value constructed at the fixed point has no related R witness, because R is abstract. Hence such a call would violate the relational interpretation of the universal quantifier. ◻

The lemma depends on the parametric model of the universal quantifier. It is not a syntactic theorem about every host language with a rank-polymorphic type. Abel, Matthes, and Uustalu embed their precise Mendler systems in a strongly normalizing Fω calculus and obtain strong normalization at that signature [AMU05].

Theorem 84.5 — Mendler iteration normalization, imported

Every well-typed term of the rank-zero Mendler iteration calculus frozen by Abel, Matthes, and Uustalu is strongly normalizing. The result extends to their displayed higher-kinded generalized iteration schemes through their translation into Fω.

Proof of Theorem 84.5 — Mendler iteration normalization, imported

Imported proof. The theorem covers that calculus. It does not cover arbitrary primitive recursion, destructors, histomorphisms, dependent eliminators, or host-language effects. The translation and normalization proof are on pp. 27–35 of [AMU05]. ◻

Exercise 84.2

★★☆ Write the full attempted algebra for out:μMFT(μMFT1). Annotate the extracted function f and the expected result with their domains. Show that replacing the result by the constant function λx. typechecks and explain why it cannot recreate the reduction cycle.

Nested parameters require a generalized fold

A lambda binder changes the type of variables in its body. Let Incr(A):=1+A with constructors zeroV:=inl() and sucV(a):=inr(a). Define the nested family Term(A)::=var(a)app(t,u)lam(b),a:A,t,u:Term(A),b:Term(Incr(A)). The recursive occurrence in the lambda constructor is at a different parameter. Thus Term is a nested datatype: its family members are defined together, and one constructor moves from A to Incr(A).

An ordinary fold to one fixed result type loses the changing parameter. The result must itself be a family N:UiUi, and every method must be polymorphic in the variable type.

Definition 84.6 — Generalized fold for nested terms

Let M,N:UiUi. Suppose v:A:UiM(A)N(A),a:A:UiN(A)×N(A)N(A),l:A:UiN(Incr(A))N(A),k:A:UiIncr(M(A))M(Incr(A)). Define gfold(v,a,l,k):B:UiTerm(M(B))N(B) by gfold(var(x)):=v(x),gfold(app(t,u)):=a(gfold(t),gfold(u)),gfold(lam(b)):=l(gfold(rename(k,b))). The omitted parameters v,a,l,k and the ambient type are unchanged in each recursive call.

The map k reconciles the two ways to extend the variable parameter: Incr(M(A)) and M(Incr(A)). Without it, the lambda clause is ill typed. Bird and Paterson derive this generalized fold and its naturality/fusion laws at the same nested representation [BP99].

For ordinary renaming, take M and N to be the identity family. Define lift(f)(zeroV):=zeroV,lift(f)(sucV(a)):=sucV(f(a)), and define rename(f,var(a)):=var(f(a)),rename(f,app(t,u)):=app(rename(f,t),rename(f,u)),rename(f,lam(b)):=lam(rename(lift(f),b)). The lambda equation is the first nonuniform recursive call: its function has changed from f:AB to lift(f):Incr(A)Incr(B).

Proposition 84.7 — Renaming fusion

Let f:AB, g:BC, and t:Term(A). Then rename(g,rename(f,t))=rename(λx.g(f(x)),t).

Proof of Proposition 84.7 — Renaming fusion

Proof. Use nested induction, strengthening the claim to every variable type A. The variable case is beta equality. The application case follows by the two induction hypotheses and congruence for app. In the lambda case, the induction hypothesis at Incr(A) gives rename(lift(g),rename(lift(f),b))=rename(lift(g)lift(f),b). Case analysis on zeroV and sucV(a) proves lift(g)lift(f)=lift(gf) pointwise. Congruence for rename(,b) and then lam closes the case. ◻

Exercise 84.3

★☆☆ Prove rename(λx.x,t)=t by nested induction generalized over the variable type. Write the lambda case, including the calculation lift(id)=id on both constructors.

Capture-free substitution

A substitution σ:ATerm(B) must be lifted under a binder. The bound variable remains bound; an old free variable is renamed past the new binder.

Definition 84.8 — Lifted substitution

For σ:ATerm(B), define liftSub(σ):Incr(A)Term(Incr(B)) by liftSub(σ)(zeroV):=var(zeroV),liftSub(σ)(sucV(a)):=rename(sucV,σ(a)).

Definition 84.9 — Nested substitution

Define subst(σ):Term(A)Term(B) by subst(σ,var(a)):=σ(a),subst(σ,app(t,u)):=app(subst(σ,t),subst(σ,u)),subst(σ,lam(b)):=lam(subst(liftSub(σ),b)).

For the open term t:=lam(app(var(zeroV),var(sucV(x)))), substituting xvar(y) gives lam(app(var(zeroV),var(sucV(y)))). The old bound occurrence remains zeroV; the free replacement is renamed by sucV. This is the observable capture-avoidance step.

Lemma 84.10 — Rename after lifted substitution

Let σ:ATerm(B) and g:BC. For every z:Incr(A), rename(lift(g),liftSub(σ)(z))=liftSub(λa.rename(g,σ(a)))(z).

Proof of Lemma 84.10 — Rename after lifted substitution

Proof. If zzeroV, both sides compute to var(zeroV). If zsucV(a), the left side is rename(lift(g),rename(sucV,σ(a))). By proposition 84.7, this equals renaming by lift(g)sucV. On each b:B, lift(g)(sucV(b))sucV(g(b)). Applying renaming congruence gives the right side. ◻

Proposition 84.11 — Renaming–substitution fusion

Let σ:ATerm(B), g:BC, and t:Term(A). Then rename(g,subst(σ,t))=subst(λa.rename(g,σ(a)),t).

Proof of Proposition 84.11 — Renaming–substitution fusion

Proof. Use nested induction generalized over A. The variable case is reflexivity. The application case uses the two induction hypotheses under app. In the lambda case, unfold both sides. The induction hypothesis at Incr(A) reduces the goal to pointwise equality of the two lifted substitutions, which is lemma 84.10. Congruence for lam closes the case. ◻

Exercise 84.4

★★☆ Let ηA(a):=var(a). Prove subst(ηA,t)=t. In the lambda case prove first that liftSub(ηA)(z)=ηIncr(A)(z) for both forms of z.

A dependent Mendler step

Iteration returns a fixed type A. A proof about the input requires a result family. At a positive F with an action, the dependent step must be told how an abstract recursive carrier embeds into the fixed point; only then can it state the indices of its induction hypotheses.

Definition 84.12 — Dependent Mendler algebra

Let F have an action, let P:μMFUj, and assume the constructor inFM. For R:Ui and e:RμMF, put IH(R,e):=r:RP(e(r)),Goal(R,e,u):=P(inFM(mapF(e,u))). A dependent Mendler algebra is Step(R):=e:RμMFIH(R,e)u:F(R)Goal(R,e,u),DMAlg(F,P):=R:UiStep(R).

The embedding e records the fixed-point value denoted by each abstract component. Without e, the motive P cannot be stated at an abstract recursive argument.

Proposition 84.13 — Dependent Mendler induction

Assume the ordinary induction principle for the selected positive fixed point. Every ψ:DMAlg(F,P) determines mindF(ψ):x:μMFP(x) with constructor equation mindF(ψ)(inFM(u))=ψ(μMF,id,mindF(ψ),u).

Proof of Proposition 84.13 — Dependent Mendler induction

Proof. Use ordinary fixed-point induction with motive P. At a layer u:F(μMF), the induction hypotheses have type P(r) at every recursive component r. Instantiate ψ with R:=μMF and e:=id. Then mapF(e,u)=u by the identity action law, so the result has type P(inFM(u)). The ordinary computation equation gives the displayed equality. ◻

The construction proves no induction principle for a negative F, because its proof uses mapF and the ordinary positive fixed-point induction principle. Dependent Mendler encodings that recover induction use additional identity-mapping or cast structure; their exact support is a separate signature, not an automatic consequence of definition 84.2.

Mixed variance and the hierarchy boundary

The operator FFoo(R):=1+((RR)×R) has both a negative and a positive occurrence of R. It has no ordinary covariant action. A Mendler algebra can nevertheless consume one layer: ϕlen(R,rec,inl):=0,ϕlen(R,rec,inr(f,r)):=suc(rec(f(r))). The embedded function f:RR may transform the child r:R, and the recursive call may consume the result. It cannot receive a larger fixed-point value containing f, because its domain is the abstract type R.

This example marks the exact strength of the catamorphism. A Mendler histomorphism additionally exposes an unrolling function for recursive components. At the same negative operator, that extra observation permits an embedded function to be applied to a value that contains the function itself. Ahn and Sheard give the concrete Foo value and loopFoo reduction in their Figure 13 [AS11].

Theorem 84.14 — Hierarchy boundary, imported

At the rank-zero calculus of Ahn and Sheard, programs defined by their mcata0 satisfy the stated termination argument, including the displayed FFoo example. Their mhisto0 is not total for arbitrary negative base operators: loopFoo applied to their value foo has an infinite reduction.

Proof of Theorem 84.14 — Hierarchy boundary, imported

Imported proof. Consequently “Mendler style” is not a termination theorem for the entire hierarchy. Iterator, primitive-recursive, destructor, course-of-value, and histomorphism interfaces must be checked separately. The terminating catamorphism instance and the divergent histomorphism trace are the rank-zero results surrounding Figure 13 on printed p. 242 of [AS11]. ◻

Exercise 84.5

★★☆ Type every component of ϕlen at an abstract R. Show that f(r):R is a legal recursive argument. Then explain why an unrolled parent of type μMFFoo is not a legal argument to the same recursive call.

The type-constraint boundary

The abstraction argument above controls one recursion scheme. Mendler’s earlier second-order calculus gives a different theorem: strong normalization for an equational recursive-type constraint set satisfying a syntactic positivity condition.

Definition 84.15 — Constraint property P

Let I be a finite set of recursive type atoms τi, and let the finite constraint set contain equations τi=Ti. Generate type equality by these equations, symmetry, transitivity, and congruence for the arrow type. Property P holds when for every C with τi=C, every occurrence of τi in C is positive. Arrow domains reverse polarity and arrow codomains preserve it.

The positive constraint τ=Aτ passes the direct polarity check: the recursive atom occurs in the codomain. Change only the direction of the final arrow: τ=τA. Now τ occurs negatively in a type equal to itself, so property P fails. The failure has an operational witness. Put δ:=λx:τ.xx. Conversion by τ=τA gives both x:τA and δ:τ, hence δδδδ. This is an explicit reducing cycle, so the changed calculus is divergent; we are not merely observing that a theorem no longer applies.

Theorem 84.16 — Constraint normalization, imported

For Mendler’s finite second-order lambda calculus with the displayed equational type constraints, property P implies strong normalization of every well-typed term. Property P is equivalent to the source’s finite partition criterion of positive and negative classes.

Proof of Theorem 84.16 — Constraint normalization, imported

Imported proof. The reducibility proof orders only the finitely many constraint classes that occur in a typing derivation, splits each class into positive and negative components, and interprets arrow domains contravariantly. Proposition 10 states the partition criterion, and the following subsection performs the strong-normalization construction [Men91]. The theorem does not range over dependent types, arbitrary type-level computation, or the later Mendler-combinator hierarchy. ◻

Exercise 84.6

★★☆ For constraints τ0=Aτ1,τ1=Bτ0, calculate the polarity of every occurrence around the cycle and test property P. Then move τ0 into the domain of the second equation and repeat the test.

Bibliographic note

The rank-polymorphic iteration and generalized higher-kinded schemes follow Abel, Matthes, and Uustalu [AMU05]. The nested de Bruijn representation, generalized fold, and fusion route follow Bird and Paterson [BP99]. The negative-datatype and histomorphism boundary follows Ahn and Sheard [AS11]. Property P and its reducibility boundary are reconstructed from Mendler’s original constraint calculus [Men91].

Suggested first pass.

None of these problems is a prerequisite for a later chapter. Begin with exercise 84.7, exercise 84.10.

Exercise 84.7

★★☆ Define Mendler algebras for list sum and list append. Expand their equations at nil and cons. For append, state which list is represented by the result type and why no destructor for the first list is required.

Exercise 84.8

★★★ Prove substitution composition for the nested terms: subst(τ,subst(σ,t))=subst(λa.subst(τ,σ(a)),t). Strengthen the induction over the variable type and prove the lifted- substitution equation needed by the lambda case before using it.

Exercise 84.9

★★★ Reconstruct the typing failure of the attempted negative destructor and the typing success of ϕlen. Then transcribe the source’s loopFoofoo example and display two repeated stages of its reduction. Keep the catamorphism and histomorphism signatures distinct.

Exercise 84.10

★★★ Practical project.mendler-nested-terms Implement in Kappa the nested variable constructors, lambda terms, lifting, renaming, and capture-free substitution of definition 84.8, definition 84.9. Maintain the invariant that entering a lambda maps the bound variable to zeroV and shifts every substituted free variable exactly once. On the named open term λ.app(zeroV,sucV(0)), substitute the free variable 0 by free variable 7 and print λ.app(zeroV,sucV(7)). Check renaming identity and the named two-step fusion instance. Reject a mutation that does not shift the substituted free variable with the witness capture-detected. The acceptance test requires the exact normal form, both laws, the rejection witness, and audit result [].

Search the book

Type to search the local edition.