-Dealing with a group
-~~~~~~~~~~~~~~~~~~~~
-Consider a mutually-recursive group, binding
-a type constructor T and a class C.
-
-Step 1: getInitialKind
- Construct a KindEnv by binding T and C to a kind variable
-
-Step 2: kcTyClDecl
- In that environment, do a kind check
-
-Step 3: Zonk the kinds
-
-Step 4: buildTyConOrClass
- Construct an environment binding T to a TyCon and C to a Class.
- a) Their kinds comes from zonking the relevant kind variable
- b) Their arity (for synonyms) comes direct from the decl
- c) The funcional dependencies come from the decl
- d) The rest comes a knot-tied binding of T and C, returned from Step 4
- e) The variances of the tycons in the group is calculated from
- the knot-tied stuff
-
-Step 5: tcTyClDecl1
- In this environment, walk over the decls, constructing the TyCons and Classes.
- This uses in a strict way items (a)-(c) above, which is why they must
- be constructed in Step 4. Feed the results back to Step 4.
- For this step, pass the is-recursive flag as the wimp-out flag
- to tcTyClDecl1.
-
-
-Step 6: Extend environment
- We extend the type environment with bindings not only for the TyCons and Classes,
- but also for their "implicit Ids" like data constructors and class selectors
-
-Step 7: checkValidTyCl
- For a recursive group only, check all the decls again, just
- to check all the side conditions on validity. We could not
- do this before because we were in a mutually recursive knot.
-
-Identification of recursive TyCons
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The knot-tying parameters: @rec_details_list@ is an alist mapping @Name@s to
-@TyThing@s.
-
-Identifying a TyCon as recursive serves two purposes
-
-1. Avoid infinite types. Non-recursive newtypes are treated as
-"transparent", like type synonyms, after the type checker. If we did
-this for all newtypes, we'd get infinite types. So we figure out for
-each newtype whether it is "recursive", and add a coercion if so. In
-effect, we are trying to "cut the loops" by identifying a loop-breaker.
-
-2. Avoid infinite unboxing. This is nothing to do with newtypes.
-Suppose we have
- data T = MkT Int T
- f (MkT x t) = f t
-Well, this function diverges, but we don't want the strictness analyser
-to diverge. But the strictness analyser will diverge because it looks
-deeper and deeper into the structure of T. (I believe there are
-examples where the function does something sane, and the strictness
-analyser still diverges, but I can't see one now.)
-
-Now, concerning (1), the FC2 branch currently adds a coercion for ALL
-newtypes. I did this as an experiment, to try to expose cases in which
-the coercions got in the way of optimisations. If it turns out that we
-can indeed always use a coercion, then we don't risk recursive types,
-and don't need to figure out what the loop breakers are.
-
-For newtype *families* though, we will always have a coercion, so they
-are always loop breakers! So you can easily adjust the current
-algorithm by simply treating all newtype families as loop breakers (and
-indeed type families). I think.
-