diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2012-01-03 10:35:08 +0000 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2012-01-03 10:35:08 +0000 |
commit | 98a642cf29781ebd33994a4ecbea6ef07f89bbed (patch) | |
tree | 3d252e6d0044764cb8c6e1c686d98065fdb35b67 /compiler/iface/BuildTyCl.lhs | |
parent | dc6f3a487331720b42b7e6c14340200c5ffcdd6f (diff) | |
download | haskell-98a642cf29781ebd33994a4ecbea6ef07f89bbed.tar.gz |
Major refactoring of CoAxioms
This patch should have no user-visible effect. It implements a
significant internal refactoring of the way that FC axioms are
handled. The ultimate goal is to put us in a position to implement
"pattern-matching axioms". But the changes here are only does
refactoring; there is no change in functionality.
Specifically:
* We now treat data/type family instance declarations very,
very similarly to types class instance declarations:
- Renamed InstEnv.Instance as InstEnv.ClsInst, for symmetry with
FamInstEnv.FamInst. This change does affect the GHC API, but
for the better I think.
- Previously, each family type/data instance declaration gave rise
to a *TyCon*; typechecking a type/data instance decl produced
that TyCon. Now, each type/data instance gives rise to
a *FamInst*, by direct analogy with each class instance
declaration giving rise to a ClsInst.
- Just as each ClsInst contains its evidence, a DFunId, so each FamInst
contains its evidence, a CoAxiom. See Note [FamInsts and CoAxioms]
in FamInstEnv. The CoAxiom is a System-FC thing, and can relate any
two types, whereas the FamInst relates directly to the Haskell source
language construct, and always has a function (F tys) on the LHS.
- Just as a DFunId has its own declaration in an interface file, so now
do CoAxioms (see IfaceSyn.IfaceAxiom).
These changes give rise to almost all the refactoring.
* We used to have a hack whereby a type family instance produced a dummy
type synonym, thus
type instance F Int = Bool -> Bool
translated to
axiom FInt :: F Int ~ R:FInt
type R:FInt = Bool -> Bool
This was always a hack, and now it's gone. Instead the type instance
declaration produces a FamInst, whose axiom has kind
axiom FInt :: F Int ~ Bool -> Bool
just as you'd expect.
* Newtypes are done just as before; they generate a CoAxiom. These
CoAxioms are "implicit" (do not generate an IfaceAxiom declaration),
unlike the ones coming from family instance declarations. See
Note [Implicit axioms] in TyCon
On the whole the code gets significantly nicer. There were consequential
tidy-ups in the vectoriser, but I think I got them right.
Diffstat (limited to 'compiler/iface/BuildTyCl.lhs')
-rw-r--r-- | compiler/iface/BuildTyCl.lhs | 75 |
1 files changed, 17 insertions, 58 deletions
diff --git a/compiler/iface/BuildTyCl.lhs b/compiler/iface/BuildTyCl.lhs index 612b098c2f..1ffabb4f73 100644 --- a/compiler/iface/BuildTyCl.lhs +++ b/compiler/iface/BuildTyCl.lhs @@ -12,13 +12,13 @@ -- for details module BuildTyCl ( - buildSynTyCon, + buildSynTyCon, buildAlgTyCon, buildDataCon, buildPromotedDataTyCon, TcMethInfo, buildClass, - distinctAbstractTyConRhs, totallyAbstractTyConRhs, - mkNewTyConRhs, mkDataTyConRhs, + distinctAbstractTyConRhs, totallyAbstractTyConRhs, + mkNewTyConRhs, mkDataTyConRhs, newImplicitBinder ) where @@ -49,69 +49,28 @@ import Unique ( getUnique ) ------------------------------------------------------ buildSynTyCon :: Name -> [TyVar] -> SynTyConRhs - -> Kind -- ^ Kind of the RHS - -> TyConParent - -> Maybe (TyCon, [Type]) -- ^ family instance if applicable + -> Kind -- ^ Kind of the RHS + -> TyConParent -> TcRnIf m n TyCon -buildSynTyCon tc_name tvs rhs rhs_kind parent mb_family - | Just fam_inst_info <- mb_family - = ASSERT( isNoParent parent ) - fixM $ \ tycon_rec -> do - { fam_parent <- mkFamInstParentInfo tc_name tvs fam_inst_info tycon_rec - ; return (mkSynTyCon tc_name kind tvs rhs fam_parent) } - - | otherwise +buildSynTyCon tc_name tvs rhs rhs_kind parent = return (mkSynTyCon tc_name kind tvs rhs parent) where kind = mkPiKinds tvs rhs_kind ------------------------------------------------------ -buildAlgTyCon :: Name -> [TyVar] -- ^ Kind variables adn type variables - -> ThetaType -- ^ Stupid theta +buildAlgTyCon :: Name + -> [TyVar] -- ^ Kind variables and type variables + -> ThetaType -- ^ Stupid theta -> AlgTyConRhs -> RecFlag - -> Bool -- ^ True <=> was declared in GADT syntax + -> Bool -- ^ True <=> was declared in GADT syntax -> TyConParent - -> Maybe (TyCon, [Type]) -- ^ family instance if applicable - -> TcRnIf m n TyCon - -buildAlgTyCon tc_name ktvs stupid_theta rhs is_rec gadt_syn - parent mb_family - | Just fam_inst_info <- mb_family - = -- We need to tie a knot as the coercion of a data instance depends - -- on the instance representation tycon and vice versa. - ASSERT( isNoParent parent ) - fixM $ \ tycon_rec -> do - { fam_parent <- mkFamInstParentInfo tc_name ktvs fam_inst_info tycon_rec - ; return (mkAlgTyCon tc_name kind ktvs stupid_theta rhs - fam_parent is_rec gadt_syn) } - - | otherwise - = return (mkAlgTyCon tc_name kind ktvs stupid_theta rhs - parent is_rec gadt_syn) - where kind = mkPiKinds ktvs liftedTypeKind - --- | If a family tycon with instance types is given, the current tycon is an --- instance of that family and we need to --- --- (1) create a coercion that identifies the family instance type and the --- representation type from Step (1); ie, it is of the form --- `Co tvs :: F ts ~ R tvs', where `Co' is the name of the coercion, --- `F' the family tycon and `R' the (derived) representation tycon, --- and --- (2) produce a `TyConParent' value containing the parent and coercion --- information. --- -mkFamInstParentInfo :: Name -> [TyVar] - -> (TyCon, [Type]) - -> TyCon - -> TcRnIf m n TyConParent -mkFamInstParentInfo tc_name tvs (family, instTys) rep_tycon - = do { -- Create the coercion - ; co_tycon_name <- newImplicitBinder tc_name mkInstTyCoOcc - ; let co_tycon = mkFamInstCo co_tycon_name tvs - family instTys rep_tycon - ; return $ FamInstTyCon family instTys co_tycon } - + -> TyCon + +buildAlgTyCon tc_name ktvs stupid_theta rhs is_rec gadt_syn parent + = mkAlgTyCon tc_name kind ktvs stupid_theta rhs parent is_rec gadt_syn + where + kind = mkPiKinds ktvs liftedTypeKind + ------------------------------------------------------ distinctAbstractTyConRhs, totallyAbstractTyConRhs :: AlgTyConRhs distinctAbstractTyConRhs = AbstractTyCon True |