Extend TyCons and DataCons to represent data instance decls
[ghc-hetmet.git] / compiler / basicTypes / DataCon.lhs
index f873977..a04f28f 100644 (file)
@@ -11,6 +11,7 @@ module DataCon (
        dataConRepType, dataConSig, dataConFullSig,
        dataConName, dataConTag, dataConTyCon, dataConUserType,
        dataConUnivTyVars, dataConExTyVars, dataConAllTyVars, dataConResTys,
+       dataConInstTys,
        dataConEqSpec, eqSpecPreds, dataConTheta, dataConStupidTheta, 
        dataConInstArgTys, dataConOrigArgTys, 
        dataConInstOrigArgTys, dataConRepArgTys, 
@@ -38,7 +39,7 @@ import Type           ( Type, ThetaType,
 import Coercion                ( isEqPred, mkEqPred )
 import TyCon           ( TyCon, FieldLabel, tyConDataCons, 
                          isProductTyCon, isTupleTyCon, isUnboxedTupleTyCon,
-                          isNewTyCon, isRecursiveTyCon )
+                          isNewTyCon, isRecursiveTyCon, tyConFamily_maybe )
 import Class           ( Class, classTyCon )
 import Name            ( Name, NamedThing(..), nameUnique, mkSysTvName, mkSystemName )
 import Var             ( TyVar, CoVar, Id, mkTyVar, tyVarKind, setVarUnique,
@@ -335,9 +336,13 @@ data DataCon
        -- An entirely separate wrapper function is built in TcTyDecls
        dcIds :: DataConIds,
 
-       dcInfix :: Bool         -- True <=> declared infix
+       dcInfix :: Bool,        -- True <=> declared infix
                                -- Used for Template Haskell and 'deriving' only
                                -- The actual fixity is stored elsewhere
+
+        dcInstTys :: Maybe [Type]  -- If this data constructor is part of a
+                                  -- data instance, then these are the type
+                                  -- patterns of the instance.
   }
 
 data DataConIds
@@ -433,6 +438,7 @@ mkDataCon :: Name
          -> [TyVar] -> [TyVar] 
          -> [(TyVar,Type)] -> ThetaType
          -> [Type] -> TyCon
+         -> Maybe [Type]
          -> ThetaType -> DataConIds
          -> DataCon
   -- Can get the tag from the TyCon
@@ -443,6 +449,7 @@ mkDataCon name declared_infix
          univ_tvs ex_tvs 
          eq_spec theta
          orig_arg_tys tycon
+         mb_typats
          stupid_theta ids
   = ASSERT( not (any isEqPred theta) )
        -- We don't currently allow any equality predicates on
@@ -459,9 +466,11 @@ mkDataCon name declared_infix
                  dcStupidTheta = stupid_theta, dcTheta = theta,
                  dcOrigArgTys = orig_arg_tys, dcTyCon = tycon, 
                  dcRepArgTys = rep_arg_tys,
-                 dcStrictMarks = arg_stricts, dcRepStrictness = rep_arg_stricts,
+                 dcStrictMarks = arg_stricts, 
+                 dcRepStrictness = rep_arg_stricts,
                  dcFields = fields, dcTag = tag, dcRepType = ty,
-                 dcIds = ids }
+                 dcIds = ids,
+                 dcInstTys = mb_typats }
 
        -- Strictness marks for source-args
        --      *after unboxing choices*, 
@@ -600,20 +609,32 @@ dataConResTys dc = [substTyVar env tv | tv <- dcUnivTyVars dc]
   where
     env = mkTopTvSubst (dcEqSpec dc)
 
+dataConInstTys :: DataCon -> Maybe [Type]
+dataConInstTys = dcInstTys
+
 dataConUserType :: DataCon -> Type
 -- The user-declared type of the data constructor
 -- in the nice-to-read form 
 --     T :: forall a. a -> T [a]
 -- rather than
 --     T :: forall b. forall a. (a=[b]) => a -> T b
+-- NB: If the constructor is part of a data instance, the result type
+-- mentions the family tycon, not the internal one.
 dataConUserType  (MkData { dcUnivTyVars = univ_tvs, 
                           dcExTyVars = ex_tvs, dcEqSpec = eq_spec,
                           dcTheta = theta, dcOrigArgTys = arg_tys,
-                          dcTyCon = tycon })
+                          dcTyCon = tycon, dcInstTys = mb_insttys })
   = mkForAllTys ((univ_tvs `minusList` map fst eq_spec) ++ ex_tvs) $
     mkFunTys (mkPredTys theta) $
     mkFunTys arg_tys $
-    mkTyConApp tycon (map (substTyVar subst) univ_tvs)
+    case mb_insttys of
+      Nothing      -> mkTyConApp tycon (map (substTyVar subst) univ_tvs)
+      Just insttys -> mkTyConApp ftycon insttys            -- data instance
+        where
+         ftycon = case tyConFamily_maybe tycon of
+                    Just ftycon -> ftycon
+                    Nothing     -> panic err
+          err    = "dataConUserType: type patterns without family tycon"
   where
     subst = mkTopTvSubst eq_spec