[TYPES] Types-list post from devriese@cs.tcd.ie requires approval
Stephanie Weirich
sweirich at cis.upenn.edu
Thu Jan 24 11:56:11 EST 2008
Hi Edsko,
What you need is a higher-kinded version of Fix (parameterized
recursive type), with the associated fold and unfold rules. You can
find these rules in the paper:
Flexible Type Analysis, Karl Crary and Stephanie Weirich, ICFP 99
http://www.seas.upenn.edu/~sweirich/papers/lx/lxpaper.pdf
--Stephanie
>
> From: Edsko de Vries <devriese at cs.tcd.ie>
> Date: January 24, 2008 11:38:26 AM EST
> To: types-list at lists.seas.upenn.edu
> Subject: Isorecursive types and type abstraction
>
>
> (Originally sent to haskell-cafe; someone suggested posting it here)
>
> Hi,
>
> Most descriptions of recursive types state that iso-recursive types
> (with explicit 'fold' and 'unfold' operators) are easy to typecheck,
> and that equi-recursive types are much more difficult. My question
> regards using iso-recursive types (explicitly, not implicitly using
> algebraic data types) together with type abstraction and application.
>
> The usual typing rules for fold and unfold are
>
> e :: Fix X. t
> ----------------------------- Unfold
> unfold e :: [X := Fix X. t] t
>
> e :: [X := Fix X. t] t
> ----------------------------- Fold
> fold e : Fix X. t
>
> This works ok for the following type:
>
> ListInt = Fix L. 1 + Int * L
>
> (where "1" is the unit type). If
>
> x :: ListInt
>
> then
>
> unfold x :: 1 + Int * ListInt
>
> using the Unfold typing rule. However, this breaks when using type
> abstraction and application. Consider the polymorphic version of list:
>
> List = Fix L. /\A. 1 + A * L A
>
> Now if we have
>
> x :: List Int
>
> we can no longer type
>
> unfold x
>
> because x does not have type (Fix ..), but ((Fix ..) Int) instead. Of
> course, we can unroll List Int by first unrolling List, and then
> re-applying the unrolled type to Int to get
>
> (/\A. 1 + A * (Fix L. /\A. 1 * L A) A) Int
>
> which can be simplified to
>
> 1 + Int * List Int
>
> but this is not usually mentioned (that I could find; in
> particular, TAPL does not mention it) and I'm worried that there
> are subtleties here that I'm missing--nor do I have an exact
> definition of what this 'extended' unrolling rule should do.
>
> Any hints or pointers to relevant literature would be appreciated!
>
> Edsko
>
> PS. One way to simplify the problem is to redefine List as
>
> List = /\A. Fix L. 1 + A * L
>
> so that List Int can easily be simplified to the right form (Fix ..);
> but that can only be done for regular datatypes. For example, the
> nested
> type
>
> Perfect = Fix L. /\A. A + Perfect (A, A)
>
> cannot be so rewritten because the argument to Perfect in the
> recursive
> call is different.
>
>
More information about the Types-list
mailing list