Version 139 (modified by chak, 11 years ago) (diff)


Type Functions: Implementation Status

Back to TypeFunctions.


  1. For Tom: Construct TyCon for type equation in tcFamInstDecl1. This needs to be a synonym tycon, which still needs to be extended to include family information.
  2. Dictionary handling for equational constraints:
    • Where do we check the details of the formation of equational constraints? (In check_pred_ty?)
    • In the case for ordinary instances in TcInstDcls.tcInstDecl2, filter the ids of the super class equalities out of map instToId sc_dicts. (They don't appear explicitly in the `Hs' representation of the methods binding.)
    • Similarly with map instToId meth_dicts in TcClassDcl.tcMethodBind Maybe we just need a special function to replace all occurences of map instToId? Occurs also in TcPat.tcConPat.
    • We also have map instToId in TcUnify.tcGen, but here I am not sure yet whether we cans imply drop the coercion variables or have to do something else.
  3. Add type synonym instances to ifaces
  4. TcSimplify: Handle the presence of EqPreds in the given set, due to appearing in signature contexts. (Including that instToId doesn't work on EqPreds.)
  5. Well-formedness checks for equational constraints (i.e., anything beyond the type arguments being boxed, rank 0 types)

Parsing and Renaming

Todo (low-level): None.

Todo (high-level):

  1. Defaults for associated type synonyms. (Having both a kind signature and vanilla synonym is problematic as in RnNames.getLocalDeclBinders its hard to see that not both of them are defining declarations, which leads to a multiple declarations error. Defaults are quite different from vanilla synonyms anyway, as they usually have tyvars on their rhs that do not occur on the lhs.)


  • Parsing and renaming of kind signatures (toplevel and in classes).
  • Parsing and renaming of indexed type declarations (toplevel and in classes).
  • Using new syntax with family and instance on top level.
  • Added -findexed-types switch.
  • Allowing type tag in export lists to list associated types in the sub-binder list of an import/export item for a class.
  • Import/export lists: ATs can be listed as subnames of classes and the data constructors of instances of a data family are subnames of that family.
  • Parsing and renaming of equational constraints in contexts.

Type Checking

Todo (low-level):

  • RHS of a type instance must be a tau type.
  • Check that patterns of type indexes don't contain type functions.
  • Implement the equation of conflict, which is local to FamInst.addLocalFamInst, for synonyms; ie, check that the left hand sides coincide under the substitution.
  • If an associated synonym has a default definition, use that in the instances. In contrast to methods, this cannot be overridden by a specialised definition. (Confluence requires that any specialised version is extensionally the same as the default.)
  • It should be ok to allow newtype instances for data families. (NB: the rhs of a newtype is guaranteed to be a lifted type.) Is this desirable?

Todo (high-level):

  1. Type checking of type functions (and hence, associated type synonyms); routines in TcUnify that need to be extended:
    • boxySplitTyConApp: The second argument (BoxyRhoType) can be a synonym family application. Then, we must produce a wanted coercion and return a HsWrapper value that applies that coercion.
    • boxySplitAppTy: Basically, the same deal as the previous.
    • boxySubMatchType: Not sure yet. Do we need to handle the case where in go one type is FunTy and the other a synonym family application? But the function doesn't handle the case where a FunTy meets a tyvar either, so its probably ok to ignore.
    • boxy_match: Not sure yet. Do we have to handle the case where t_ty is a synonym family application? On the other hand, this prematching seems to be an approximation. How much does it hurt if we just ignore this?
    • boxy_lub: Unclear. Also seems to approximate.
    • tcSubExp: Defer to boxy matching if we have a synonym family application.
    • uTysOuter, u_tys, uPred, uVar, and their intefaces boxyUnify, boxyUnifyList, unifyType, unifyPred, unifyTheta, and unifyTypeList: Generate wanted equalities and produce coercion(s). !!!Still need to check usage patterns!!!
    To make things easy, we might want to always return a HsWrapper value (unless the unification fails), which is WpHole whenever the coercion is empty. The disadvantage is that this blows the tree between type checking and desugaring up. An alternative is to return the coercion only when needed, but write some auxilliary functions that take the result of boxySplitTyConApp and friends and turn the optional coercion result in an always present (real Haskell) function that we always apply to the type-checked pattern (in TcPat) or expression. It is simply id when we don't need a coercion.


  • Arguments and results of synonym families are always tau types. Then, boxy subsumption becomes easy to handle. When we have a synonym family application, we defer to boxy matching (i.e., unification) and if that comes up with a coercion, we return it as the subsumption coercion.
  1. Type checking in the presence of associated synonym defaults. (Default AT synonyms are only allowed for ATs defined in the same class.)
  2. Type check functional dependencies as type functions.


  • Kind and type checking of kind signatures.
  • Kind and type checking of instance declarations of indexed types.
  • Wrapper generation and type checking of pattern matching for indexed data and newtypes.
  • Consistency checking for family instances.


Todo (low-level): None.

Todo (high-level):

  1. Extend interface files to include equality axioms:
    • How do we exactly want to represent type equations in interface files?
      • SPJ pointed out that instances are maintained in InstEnv.InstEnv with different values for the home packages and others. Type instances may have to be maintained in a similar way, as they are also incrementally collected during compiling a program. (We probably include them in the same structure, as they will also be of type InstInfo.)
      • IfaceInst contains the instance declaration information for interfaces.
      Answer: We don't put anything extra into interface files. Instead, we derive the information corresponding toIfaceInst list in ModIface and the Instance list in ModDetails from the interface declarations and type environment, respectively. I.e., it is the type instances that carry the whole payload. Update: We may actually want to put a rough match signature in the iface seperate from the full instance declaration, so we can delay type checking the full instance declaration until we get a rough match. (This makes only sense for type instances, not for data instances, as the latter are loaded when their constructors are mentioned. Well actually, it does make sense for data instances as far as loading them for overlap checking is concerned.)
  1. Emit type function instances to ifaces.


  • Representation of family kind signatures as TyCon.TyCons.
  • Extension of Class.Class by associated TyCons.
  • Extension of TyCon.TyCon with a reference to the parent TyCon for data instances.
  • Extension of DataCon.DataCon with instance types for constructors belonging to data instances.
  • Extension of TyCon.TyCon such that the parent of a data instance is paired with a coercion identifying family instance and representation type.
  • For indexed data types, the datacon wrapper uses data instance coercion and pattern matching casts the scrutinee via an ExprCoFn in a CoPat.
  • Import and exporting.
  • Generation and plumbing through of rough matches.
  • Equational constraints in contexts.



  • Compile libraries with CoreLint.