Following Wadler's paper "Recursive types for free" and having spent some months on reconstructing the proof that $\exists A. ~ A \times (A\to F~ A)$ is the terminal $F$-coalgebra, I am still not able to prove one step that appears to be important.
Wadler denotes $\exists A. ~ A \times (A\to F~ A)$ by T
and defines the functions:
unfold : forall X. (X -> F X) -> X -> T
unfold = \(X : *) -> \(k : X -> F X) -> \(x : T) -> (X, (k,x))
out : T -> F T
out = \(t : T) -> case t of { (X,(k,x)) -> F (unfold X k) (k x) }
in : F T -> T
in = unfold (F T) (F out)
In Wadler's notation, the tuple (X, x)
is a packed form of the existentially-typed value built from a specific type X
and a value x : P X
for some type constructor P
.
The main question is to prove that out
and in
are inverses. Equivalently, to prove that any $F$-coalgebra has a unique map to T
.
Wadler does not actually show a detailed proof but mentions that the proof requires the parametricity assumption for unfold
:
k unfold X k
X ----------> F X X -----------> T
| | | |
| | | |
h | | F h implies h | | id
| | | |
| | | |
X' ---------> F X' X' ----------> T
k' unfold X' k'
The precondition is that h
is an F-coalgebra morphism between F-coalgebras X
and X'
.
This can be written as the relational property that, for any types $X$, $X'$, for any functions $h : X\to X'$, $k : X\to F~X$, $k' : X'\to F~X'$, such that $F(h) \circ k = k'\circ h$ we will then have $\mathrm{unfold}~X~k = \mathrm{unfold}~X'~k' \circ h$. Indeed, this is a consequence of the "free theorem" (i.e., the relational naturality law) for the type signature of unfold
.
I have applied this assumption, and I tried applying various other "free theorems", but I still cannot derive $\mathrm{in} \circ \mathrm{out} = \mathrm{id}$. I can only derive a weaker property: $$\mathrm{in} \circ \mathrm{out} = \mathrm{unfold} ~T~\mathrm{out}$$
So, it remains to prove that $\mathrm{unfold} ~T~\mathrm{out} = \mathrm{id}$ but I don't see how this can be proved from parametricity assumptions.
In other words, what I am missing is to prove that, for any value t : T
,
$$ \mathrm{unfold} ~T~\mathrm{out}~t =t$$
I also tried to encode the existential type in System F. For instance, we then get:
T = forall R. (forall X. (X -> F X) -> X -> R) -> R
I applied relational parametricity to derive the free theorem for T
, but that did not seem to help. I can show that the function $\mathrm{unfold} ~T~\mathrm{out}$ of type $T\to T$ is idempotent, but I cannot show that it is an identity function.
However, I can make progress with a weaker assumption: that any value of type T
is a result of unfold
applied to some arguments (not necessarily to T
and out
). In other words, it appears to be necessary to assume that unfold
is surjective. But it is not clear how to prove that. (A related question is Is the encoding of existential types in System F adequate? .)
If we assume that any value of type T
is obtained as unfold R c r
with some type R
and some c : R -> F R
, r : R
then we can apply the "free theorem" of unfold
with types X = R
and X' = T
, with functions h = unfold R c
, k = c
, k' = out
, and obtain (having already shown that unfold R c
is an F-coalgebra morphism):
unfold R c r = unfold T out (unfold R c r)
If we denote t = unfold R c r
then we obtain the desired equation t = unfold T out t
.
But this equation holds only for t : T
that are obtained by applying unfold
to some arguments (t = unfold R c r
). The equation t = unfold T out t
does not follow for arbitrary t : T
withough the assumption that any value of type T
is obtained as unfold R c r
with some R
, c
, r
.
So, the question is, how to prove t = unfold T out t
for arbitrary t : T
, or how to prove that an arbitrary t : T
can be expressed as unfold R c r
. (Can we prove that in System F with the encoding of T
as shown above, and using parametricity?)
With that, I can complete the proof that in
and out
are inverses, and that T
is a terminal $F$-coalgebra.
Am I missing something? Wadler also cryptically says that another necessary assumption is "the surjective pairing rule" that he writes as:
case t of {(X,y) -> h (X,y)} = h t
This is perhaps related to my missing assumption that unfold
is surjective. However, I cannot make sense of Wadler's notation as written in this equation. The function h
seems to be used in a contradictory way. In the left-hand side, the type of h
's argument is the type of a pair (X, y)
- a (dependent) pair consisting of a type and a value. In the right-hand side, the type of h
's argument is the existential type that does not expose its encapsulated type or value. It is not the type of a pair.
The function h
does not seem to be possible to typecheck if encoded in System F. The existential type is encoded as a function, not as a pair.
What is the missing step or a missing assumption here?