[project @ 1998-02-03 17:13:54 by simonm]
[ghc-hetmet.git] / ghc / compiler / types / TyCon.lhs
index ada7c8d..0ce00b1 100644 (file)
@@ -1,18 +1,17 @@
-%
+
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 \section[TyCon]{The @TyCon@ datatype}
 
 \begin{code}
-#include "HsVersions.h"
-
 module TyCon(
-       TyCon(..),      -- NB: some pals need to see representation
+       TyCon,
 
-       SYN_IE(Arity), NewOrData(..),
+       Arity, NewOrData(..),
 
-       isFunTyCon, isPrimTyCon, isBoxedTyCon,
-       isAlgTyCon, isDataTyCon, isSynTyCon, isNewTyCon, maybeNewTyCon,
+       isFunTyCon, isPrimTyCon, isBoxedTyCon, isProductTyCon,
+       isAlgTyCon, isDataTyCon, isSynTyCon, isNewTyCon, 
+       isEnumerationTyCon, isTupleTyCon, 
 
        mkDataTyCon,
        mkFunTyCon,
@@ -30,56 +29,43 @@ module TyCon(
        tyConDerivings,
        tyConTheta,
        tyConPrimRep,
-       synTyConArity,
+       tyConArity,
+       tyConClass_maybe,
        getSynTyConDefn,
 
-        maybeTyConSingleCon,
-       isEnumerationTyCon, isTupleTyCon,
-       derivedClasses
+        maybeTyConSingleCon
 ) where
 
-CHK_Ubiq()     -- debugging consistency check
+#include "HsVersions.h"
 
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ <= 201
-IMPORT_DELOOPER(TyLoop) ( SYN_IE(Type), GenType,
-                         SYN_IE(Class), GenClass,
-                         SYN_IE(Id), GenId,
-                         splitSigmaTy, splitFunTy,
-                         tupleCon, isNullaryDataCon, idType
-                         --LATER: specMaybeTysSuffix
-                       )
-#else
-import {-# SOURCE #-} Type  ( Type, splitSigmaTy, splitFunTy  )
+import {-# SOURCE #-} Type  ( Type )
 import {-# SOURCE #-} Class ( Class )
-import {-# SOURCE #-} Id    ( Id, isNullaryDataCon, idType )
+import {-# SOURCE #-} Id    ( Id, isNullaryDataCon )
 import {-# SOURCE #-} TysWiredIn ( tupleCon )
-#endif
 
-import BasicTypes      ( SYN_IE(Arity), NewOrData(..) )
-import TyVar           ( GenTyVar, alphaTyVars, alphaTyVar, betaTyVar, SYN_IE(TyVar) )
-import Usage           ( GenUsage, SYN_IE(Usage) )
-import Kind            ( Kind, mkBoxedTypeKind, mkArrowKind, resultKind, argKind )
 
+import BasicTypes      ( Arity, NewOrData(..), RecFlag(..) )
+import TyVar           ( GenTyVar, alphaTyVars, alphaTyVar, betaTyVar, TyVar )
+import Kind            ( Kind, mkBoxedTypeKind, mkTypeKind, mkUnboxedTypeKind,
+                         mkArrowKind, resultKind, argKind
+                       )
 import Maybes
 import Name            ( Name, nameUnique, mkWiredInTyConName, NamedThing(getName) )
 import Unique          ( Unique, funTyConKey, Uniquable(..) )
-import Pretty          ( Doc )
-import PrimRep         ( PrimRep(..) )
-import PrelMods                ( gHC__, pREL_TUP, pREL_BASE )
-import Lex             ( mkTupNameStr )
-import SrcLoc          ( SrcLoc, mkBuiltinSrcLoc )
-import Util            ( nOfThem, isIn, Ord3(..), panic, panic#, assertPanic )
+import PrimRep         ( PrimRep(..), isFollowableRep )
+import PrelMods                ( pREL_GHC )
+import Util            ( panic )
 \end{code}
 
 \begin{code}
 data TyCon
   = FunTyCon           -- Kind = Type -> Type -> Type
 
-  | DataTyCon  Unique{-TyConKey-}
+  | DataTyCon  Unique
                Name
                Kind
                [TyVar]
-               [(Class,Type)]  -- Its context
+               [(Class,[Type])]        -- Its context
                [Id{-DataCon-}] -- Its data constructors, with fully polymorphic types
                                --      This list can be empty, when we import a data type abstractly,
                                --      either (a) the interface is hand-written and doesn't give
@@ -87,7 +73,11 @@ data TyCon
                                --             (b) in a quest for fast compilation we don't import 
                                --                 the constructors
                [Class]         -- Classes which have derived instances
+               (Maybe Class)   -- Nothing for ordinary types; Just c for the type constructor
+                               -- for dictionaries of class c.
                NewOrData
+               RecFlag         -- Tells whether the data type is part of 
+                               -- a mutually-recursive group or not
 
   | TupleTyCon Unique          -- cached
                Name            -- again, we could do without this, but
@@ -99,9 +89,10 @@ data TyCon
                        --      -> BoxedTypeKind
 
   | PrimTyCon          -- Primitive types; cannot be defined in Haskell
-       Unique          -- Always unboxed; hence never represented by a closure
+       Unique          -- Always unpointed; hence never represented by a closure
        Name            -- Often represented by a bit-pattern for the thing
        Kind            -- itself (eg Int#), but sometimes by a pointer to
+       Arity           -- the thing.
        PrimRep
 
   | SpecTyCon          -- A specialised TyCon; eg (Arr# Int#), or (List Int#)
@@ -128,19 +119,26 @@ data TyCon
 
 \begin{code}
 mkFunTyCon     = FunTyCon
-mkFunTyConName = mkWiredInTyConName funTyConKey gHC__ SLIT("->") FunTyCon
+mkFunTyConName = mkWiredInTyConName funTyConKey pREL_GHC SLIT("->") FunTyCon
 
 mkSpecTyCon  = SpecTyCon
 mkTupleTyCon = TupleTyCon
 
 mkDataTyCon name = DataTyCon (nameUnique name) name
-mkPrimTyCon name = PrimTyCon (nameUnique name) name
+
+mkPrimTyCon name arity rep 
+  = PrimTyCon (nameUnique name) name (mk_kind arity) arity rep
+  where
+    mk_kind 0 | isFollowableRep rep = mkBoxedTypeKind  -- Represented by a GC-ish ptr
+             | otherwise           = mkUnboxedTypeKind -- Represented by a non-ptr
+    mk_kind n = mkTypeKind `mkArrowKind` mk_kind (n-1)
+
 mkSynTyCon  name = SynTyCon  (nameUnique name) name
 
 isFunTyCon FunTyCon = True
 isFunTyCon _ = False
 
-isPrimTyCon (PrimTyCon _ _ _ _) = True
+isPrimTyCon (PrimTyCon _ _ _ _ _) = True
 isPrimTyCon _ = False
 
 -- At present there are no unboxed non-primitive types, so
@@ -148,30 +146,36 @@ isPrimTyCon _ = False
 isBoxedTyCon = not . isPrimTyCon
 
 -- isAlgTyCon returns True for both @data@ and @newtype@
-isAlgTyCon (DataTyCon _ _ _ _ _ _ _ _) = True
-isAlgTyCon (TupleTyCon _ _ _)         = True
-isAlgTyCon other                      = False
+isAlgTyCon (DataTyCon _ _ _ _ _ _ _ _ _ _) = True
+isAlgTyCon (TupleTyCon _ _ _)             = True
+isAlgTyCon other                          = False
 
 -- isDataTyCon returns False for @newtype@.
-isDataTyCon (DataTyCon _ _ _ _ _ _ _ DataType) = True
-isDataTyCon (TupleTyCon _ _ _)                = True
-isDataTyCon other                             = False
-
-maybeNewTyCon :: TyCon -> Maybe ([TyVar], Type)        -- Returns representation type info
-maybeNewTyCon (DataTyCon _ _ _ _ _ (con:null_cons) _ NewType) 
-  = ASSERT( null null_cons && null null_tys)
-    Just (tyvars, rep_ty)
-  where
-    (tyvars, theta, tau)      = splitSigmaTy (idType con)
-    (rep_ty:null_tys, res_ty) = splitFunTy tau
+isDataTyCon (DataTyCon _ _ _ _ _ _ _ _ DataType _) = True
+isDataTyCon (TupleTyCon _ _ _)                            = True
+isDataTyCon other                                 = False
 
-maybeNewTyCon other = Nothing
+isNewTyCon (DataTyCon _ _ _ _ _ _ _ _ NewType _) = True 
+isNewTyCon other                                = False
 
-isNewTyCon (DataTyCon _ _ _ _ _ _ _ NewType) = True 
-isNewTyCon other                            = False
+-- A "product" tycon is non-recursive and has one constructor,
+-- whether DataType or NewType
+isProductTyCon (TupleTyCon _ _ _)                          = True
+isProductTyCon (DataTyCon _ _ _ _ _ [c] _ _ _ NonRecursive) = True
+isProductTyCon other                                       = False
 
 isSynTyCon (SynTyCon _ _ _ _ _ _) = True
 isSynTyCon _                     = False
+
+isEnumerationTyCon (TupleTyCon _ _ arity)
+  = arity == 0
+isEnumerationTyCon (DataTyCon _ _ _ _ _ data_cons _ _ DataType _)
+  = not (null data_cons) && all isNullaryDataCon data_cons
+isEnumerationTyCon other = False
+
+isTupleTyCon (TupleTyCon _ _ arity) = arity >= 2    -- treat "0-tuple" specially
+isTupleTyCon (SpecTyCon tc tys)     = isTupleTyCon tc
+isTupleTyCon other                 = False
 \end{code}
 
 \begin{code}
@@ -180,10 +184,10 @@ kind1 = mkBoxedTypeKind `mkArrowKind` mkBoxedTypeKind
 kind2 = mkBoxedTypeKind `mkArrowKind` kind1
 
 tyConKind :: TyCon -> Kind
-tyConKind FunTyCon                      = kind2
-tyConKind (DataTyCon _ _ kind _ _ _ _ _) = kind
-tyConKind (PrimTyCon _ _ kind _)        = kind
-tyConKind (SynTyCon _ _ k _ _ _)        = k
+tyConKind FunTyCon                          = kind2
+tyConKind (DataTyCon _ _ kind _ _ _ _ _ _ _) = kind
+tyConKind (PrimTyCon _ _ kind _ _)          = kind
+tyConKind (SynTyCon _ _ k _ _ _)            = k
 
 tyConKind (TupleTyCon _ _ n)
   = mkArrow n
@@ -204,26 +208,30 @@ tyConKind (SpecTyCon tc tys)
 
 \begin{code}
 tyConUnique :: TyCon -> Unique
-tyConUnique FunTyCon                      = funTyConKey
-tyConUnique (DataTyCon uniq _ _ _ _ _ _ _) = uniq
-tyConUnique (TupleTyCon uniq _ _)         = uniq
-tyConUnique (PrimTyCon uniq _ _ _)        = uniq
-tyConUnique (SynTyCon uniq _ _ _ _ _)      = uniq
-tyConUnique (SpecTyCon _ _ )              = panic "tyConUnique:SpecTyCon"
-
-synTyConArity :: TyCon -> Maybe Arity -- Nothing <=> not a syn tycon
-synTyConArity (SynTyCon _ _ _ arity _ _) = Just arity
-synTyConArity _                                 = Nothing
+tyConUnique FunTyCon                          = funTyConKey
+tyConUnique (DataTyCon uniq _ _ _ _ _ _ _ _ _) = uniq
+tyConUnique (TupleTyCon uniq _ _)             = uniq
+tyConUnique (PrimTyCon uniq _ _ _ _)          = uniq
+tyConUnique (SynTyCon uniq _ _ _ _ _)          = uniq
+tyConUnique (SpecTyCon _ _ )                  = panic "tyConUnique:SpecTyCon"
+
+tyConArity :: TyCon -> Arity 
+tyConArity FunTyCon                            = 2
+tyConArity (DataTyCon _ _ _ tyvars _ _ _ _ _ _) = length tyvars
+tyConArity (TupleTyCon _ _ arity)              = arity
+tyConArity (PrimTyCon _ _ _ arity _)           = arity 
+tyConArity (SynTyCon _ _ _ arity _ _)          = arity
+tyConArity (SpecTyCon _ _ )                    = panic "tyConArity:SpecTyCon"
 \end{code}
 
 \begin{code}
 tyConTyVars :: TyCon -> [TyVar]
-tyConTyVars FunTyCon                     = [alphaTyVar,betaTyVar]
-tyConTyVars (DataTyCon _ _ _ tvs _ _ _ _) = tvs
-tyConTyVars (TupleTyCon _ _ arity)       = take arity alphaTyVars
-tyConTyVars (SynTyCon _ _ _ _ tvs _)      = tvs
+tyConTyVars FunTyCon                         = [alphaTyVar,betaTyVar]
+tyConTyVars (DataTyCon _ _ _ tvs _ _ _ _ _ _) = tvs
+tyConTyVars (TupleTyCon _ _ arity)           = take arity alphaTyVars
+tyConTyVars (SynTyCon _ _ _ _ tvs _)          = tvs
 #ifdef DEBUG
-tyConTyVars (PrimTyCon _ _ _ _)                  = panic "tyConTyVars:PrimTyCon"
+tyConTyVars (PrimTyCon _ _ _ _ _)        = panic "tyConTyVars:PrimTyCon"
 tyConTyVars (SpecTyCon _ _ )             = panic "tyConTyVars:SpecTyCon"
 #endif
 \end{code}
@@ -232,34 +240,34 @@ tyConTyVars (SpecTyCon _ _ )                = panic "tyConTyVars:SpecTyCon"
 tyConDataCons :: TyCon -> [Id]
 tyConFamilySize  :: TyCon -> Int
 
-tyConDataCons (DataTyCon _ _ _ _ _ data_cons _ _) = data_cons
-tyConDataCons (TupleTyCon _ _ a)                 = [tupleCon a]
-tyConDataCons other                              = []
+tyConDataCons (DataTyCon _ _ _ _ _ data_cons _ _ _ _) = data_cons
+tyConDataCons (TupleTyCon _ _ a)                     = [tupleCon a]
+tyConDataCons other                                  = []
        -- You may think this last equation should fail,
        -- but it's quite convenient to return no constructors for
        -- a synonym; see for example the call in TcTyClsDecls.
 
-tyConFamilySize (DataTyCon _ _ _ _ _ data_cons _ _) = length data_cons
-tyConFamilySize (TupleTyCon _ _ _)                 = 1
+tyConFamilySize (DataTyCon _ _ _ _ _ data_cons _ _ _ _) = length data_cons
+tyConFamilySize (TupleTyCon _ _ _)                     = 1
 #ifdef DEBUG
---tyConFamilySize other = pprPanic "tyConFamilySize:" (pprTyCon PprDebug other)
+--tyConFamilySize other = pprPanic "tyConFamilySize:" (pprTyCon other)
 #endif
 
 tyConPrimRep :: TyCon -> PrimRep
-tyConPrimRep (PrimTyCon _ _ _ rep) = rep
-tyConPrimRep _                    = PtrRep
+tyConPrimRep (PrimTyCon _ __  _ rep) = rep
+tyConPrimRep _                      = PtrRep
 \end{code}
 
 \begin{code}
 tyConDerivings :: TyCon -> [Class]
-tyConDerivings (DataTyCon _ _ _ _ _ _ derivs _) = derivs
-tyConDerivings other                           = []
+tyConDerivings (DataTyCon _ _ _ _ _ _ derivs _ _ _) = derivs
+tyConDerivings other                               = []
 \end{code}
 
 \begin{code}
-tyConTheta :: TyCon -> [(Class,Type)]
-tyConTheta (DataTyCon _ _ _ _ theta _ _ _) = theta
-tyConTheta (TupleTyCon _ _ _)             = []
+tyConTheta :: TyCon -> [(Class, [Type])]
+tyConTheta (DataTyCon _ _ _ _ theta _ _ _ _ _) = theta
+tyConTheta (TupleTyCon _ _ _)                 = []
 -- should ask about anything else
 \end{code}
 
@@ -271,24 +279,18 @@ getSynTyConDefn (SynTyCon _ _ _ _ tyvars ty) = (tyvars,ty)
 \begin{code}
 maybeTyConSingleCon :: TyCon -> Maybe Id
 
-maybeTyConSingleCon (TupleTyCon _ _ arity)        = Just (tupleCon arity)
-maybeTyConSingleCon (DataTyCon _ _ _ _ _ [c] _ _) = Just c
-maybeTyConSingleCon (DataTyCon _ _ _ _ _ _   _ _) = Nothing
-maybeTyConSingleCon (PrimTyCon _ _ _ _)                  = Nothing
-maybeTyConSingleCon (SpecTyCon tc tys)            = panic "maybeTyConSingleCon:SpecTyCon"
+maybeTyConSingleCon (TupleTyCon _ _ arity)            = Just (tupleCon arity)
+maybeTyConSingleCon (DataTyCon _ _ _ _ _ [c] _ _ _ _) = Just c
+maybeTyConSingleCon (DataTyCon _ _ _ _ _ _   _ _ _ _) = Nothing
+maybeTyConSingleCon (PrimTyCon _ _ _ _ _)             = Nothing
+maybeTyConSingleCon (SpecTyCon tc tys)                = panic "maybeTyConSingleCon:SpecTyCon"
                                                  -- requires DataCons of TyCon
+\end{code}
 
-isEnumerationTyCon (TupleTyCon _ _ arity)
-  = arity == 0
-isEnumerationTyCon (DataTyCon _ _ _ _ _ data_cons _ _)
-  = not (null data_cons) && all isNullaryDataCon data_cons
-
-
-isTupleTyCon (TupleTyCon _ _ arity) = arity >= 2    -- treat "0-tuple" specially
-isTupleTyCon (SpecTyCon tc tys)     = isTupleTyCon tc
-isTupleTyCon other                 = False
-
-
+\begin{code}
+tyConClass_maybe :: TyCon -> Maybe Class
+tyConClass_maybe (DataTyCon _ _ _ _ _ _ _ maybe_cls _ _) = maybe_cls
+tyConClass_maybe other_tycon                            = Nothing
 \end{code}
 
 @derivedFor@ reports if we have an {\em obviously}-derived instance
@@ -298,12 +300,6 @@ function doesn't deal with that.
 
 ToDo: what about derivings for specialised tycons !!!
 
-\begin{code}
-derivedClasses :: TyCon -> [Class]
-derivedClasses (DataTyCon _ _ _ _ _ _ derivs _) = derivs
-derivedClasses something_weird                 = []
-\end{code}
-
 %************************************************************************
 %*                                                                     *
 \subsection[TyCon-instances]{Instance declarations for @TyCon@}
@@ -316,38 +312,29 @@ The strictness analyser needs @Ord@. It is a lexicographic order with
 the property @(a<=b) || (b<=a)@.
 
 \begin{code}
-instance Ord3 TyCon where
-  cmp tc1 tc2 = uniqueOf tc1 `cmp` uniqueOf tc2
-
 instance Eq TyCon where
-    a == b = case (a `cmp` b) of { EQ_ -> True;   _ -> False }
-    a /= b = case (a `cmp` b) of { EQ_ -> False;  _ -> True  }
+    a == b = case (a `compare` b) of { EQ -> True;   _ -> False }
+    a /= b = case (a `compare` b) of { EQ -> False;  _ -> True  }
 
 instance Ord TyCon where
-    a <= b = case (a `cmp` b) of { LT_ -> True;  EQ_ -> True;  GT__ -> False }
-    a <         b = case (a `cmp` b) of { LT_ -> True;  EQ_ -> False; GT__ -> False }
-    a >= b = case (a `cmp` b) of { LT_ -> False; EQ_ -> True;  GT__ -> True  }
-    a >         b = case (a `cmp` b) of { LT_ -> False; EQ_ -> False; GT__ -> True  }
-    _tagCmp a b = case (a `cmp` b) of { LT_ -> _LT; EQ_ -> _EQ; GT__ -> _GT }
+    a <= b = case (a `compare` b) of { LT -> True;  EQ -> True;  GT -> False }
+    a <         b = case (a `compare` b) of { LT -> True;  EQ -> False; GT -> False }
+    a >= b = case (a `compare` b) of { LT -> False; EQ -> True;  GT -> True  }
+    a >         b = case (a `compare` b) of { LT -> False; EQ -> False; GT -> True  }
+    compare a b = uniqueOf a `compare` uniqueOf b
 
 instance Uniquable TyCon where
-    uniqueOf (DataTyCon  u _ _ _ _ _ _ _) = u
-    uniqueOf (TupleTyCon u _ _)                  = u
-    uniqueOf (PrimTyCon  u _ _ _)        = u
-    uniqueOf (SynTyCon   u _ _ _ _ _)    = u
-    uniqueOf tc@(SpecTyCon _ _)                  = panic "uniqueOf:SpecTyCon"
-    uniqueOf tc                                  = uniqueOf (getName tc)
+    uniqueOf tc = tyConUnique tc
 \end{code}
 
 \begin{code}
 instance NamedThing TyCon where
-    getName (DataTyCon _ n _ _ _ _ _ _) = n
-    getName (PrimTyCon _ n _ _)                = n
-    getName (SpecTyCon tc _)           = getName tc
-    getName (SynTyCon _ n _ _ _ _)     = n
-    getName FunTyCon                   = mkFunTyConName
-    getName (TupleTyCon _ n _)         = n
-    getName tc                         = panic "TyCon.getName"
+    getName (DataTyCon _ n _ _ _ _ _ _ _ _) = n
+    getName (PrimTyCon _ n _ _ _)          = n
+    getName (SpecTyCon tc _)               = getName tc
+    getName (SynTyCon _ n _ _ _ _)         = n
+    getName FunTyCon                       = mkFunTyConName
+    getName (TupleTyCon _ n _)             = n
 
 {- LATER:
     getName (SpecTyCon tc tys) = let (OrigName m n) = origName "????" tc in
@@ -355,5 +342,4 @@ instance NamedThing TyCon where
     getName    other_tc           = moduleNamePair (expectJust "tycon1" (getName other_tc))
     getName other                           = Nothing
 -}
-
 \end{code}