Skip to content
Snippets Groups Projects
Commit 25a30f57 authored by Max New's avatar Max New
Browse files

show how recursive types work as least pre-fixed points

parent 93199cbc
No related branches found
No related tags found
No related merge requests found
......@@ -61,6 +61,89 @@ equi-dynamic with their one level unrolling?
rec X. A == A[rec X.A]
Or should we say that in fact they are *least/greatest fixed points*
Or should we say that in fact they are *least pre-fixed points*
in the precision ordering? I haven't thought through the consequences
yet but my gut says least fixed point will be more useful.
The lfp rules are simple. We say first that the type mu X. A is a pre-fixed point of X.A:
-----------------------
A[mu X. A/X] <= mu X. A
and second that it is the *least* such pre-fixed point:
A[A'/X] <= A'
-------------
mu X. A <= A'
From this we can derive that lfp are functorial:
X <= X' |- A <= A'
--------------------
mu X. A <= mu X'. A'
by using the lfp property and monotonicity of all connectives:
A[mu X'. A'/X] <= A'[mu X'. A'/X'] <= mu X'. A'
-----------------------------------------------
A[mu X'. A'/X] <= mu X'. A'
---------------------------
mu X. A <= mu X'. A'
* Recursive Types as a Precision-Least Pre-fixed Point
Here's an interesting idea, somewhat inspired by denotational
semantics. What if the recursive type mu X. A were just *defined* to
be the least pre-fixed point of X.A in the dynamism ordering? That is,
we treat mu X. A similar to the dynamic type ? in that we only
interact with it via casts.
Then we could define for example:
G |- V : A[mu X. A/X]
------------------------------------------------------
G |- roll(V) : mu X. A =: <mu X. A <--< A[mu X. A/X]>V
and
G |- V : mu X. A
------------------------------------------------------------
G |- unroll(V) : A[mu X. A/X] =: <A[mu X.A/X] <--< mu X.A>V
where the dynamism derivation of the latter comes from
A <= A and A[mu X. A/X] <= mu X.A
-------------------------------subst
A[A[mu X.A/X]/X] <= A[mu X.A /X]
----------------------least pre-fixed point
mu X. A <= A[mu X.A/X]
we can prove that roll, unroll form an isomorphism from our proof that
equi-dynamic types are isomorphic.
What's even cooler than that is we can derive reduction rules:
Say we have a derivation
A[A'/X] <= A'
-------------lfp
mu X. A <= A'
Then there is an upcast
<A' <--< mu X. A>V
We can derive a reduction rule for this cast when it is applied to roll:
<A' <--< mu X.A>roll(V)
= <A' <--< mu X.A><mu X. A <--< A[mu X.A/X]>V
= <A' <--< A[A'/X]><A[A'/X] <--< A[mu X.A/X]>V
By coherence of upcasts, we need only verify that appropriate type
dynamism derivations can be constructed:
1. A[A'/X] <= A'
2. A <= A and mu X.A <= A'
-----------------------------subst
A[mu X.A/X] <= A[A'/X]
TODO: look at the downcasts involving mu, and dualize everything for
computation types.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment