2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[TyCon]{The @TyCon@ datatype}
13 AlgTyConRhs(..), visibleDataCons,
15 isFunTyCon, isUnLiftedTyCon, isProductTyCon,
16 isAlgTyCon, isDataTyCon, isSynTyCon, isNewTyCon, isPrimTyCon,
17 isEnumerationTyCon, isGadtSyntaxTyCon,
18 isTupleTyCon, isUnboxedTupleTyCon, isBoxedTupleTyCon, tupleTyConBoxity,
19 isRecursiveTyCon, newTyConRep, newTyConRhs, newTyConCo,
20 isHiBootTyCon, isSuperKindTyCon,
21 isCoercionTyCon_maybe, isCoercionTyCon,
23 tcExpandTyCon_maybe, coreExpandTyCon_maybe, stgExpandTyCon_maybe,
25 makeTyConAbstract, isAbstractTyCon,
27 mkForeignTyCon, isForeignTyCon,
44 algTyConRhs, tyConDataCons, tyConDataCons_maybe, tyConFamilySize,
48 isClassTyCon, tyConClass_maybe,
49 synTyConDefn, synTyConRhs,
50 tyConExtName, -- External name for foreign types
58 #include "HsVersions.h"
60 import {-# SOURCE #-} TypeRep ( Kind, Type, Coercion, PredType )
61 import {-# SOURCE #-} DataCon ( DataCon, isVanillaDataCon )
63 import Var ( TyVar, Id )
64 import Class ( Class )
65 import BasicTypes ( Arity, RecFlag(..), Boxity(..), isBoxed )
66 import Name ( Name, nameUnique, NamedThing(getName) )
67 import PrelNames ( Unique, Uniquable(..) )
68 import Maybes ( orElse )
73 %************************************************************************
75 \subsection{The data type}
77 %************************************************************************
82 tyConUnique :: Unique,
89 | AlgTyCon { -- Data type, and newtype decls.
90 -- All lifted, all boxed
91 tyConUnique :: Unique,
96 tyConTyVars :: [TyVar], -- Scopes over (a) the [PredType] in AlgTyConRhs.DataTyCon
97 -- (b) the cached types in AlgTyConRhs.NewTyCon
98 -- But not over the data constructors
99 algTcSelIds :: [Id], -- Its record selectors (empty if none):
101 algTcGadtSyntax :: Bool, -- True <=> the data type was declared using GADT syntax
102 -- That doesn't mean it's a true GADT; only that the "where"
103 -- form was used. This field is used only to guide
105 algTcStupidTheta :: [PredType], -- The "stupid theta" for the data type
106 -- (always empty for GADTs)
108 algTcRhs :: AlgTyConRhs, -- Data constructors in here
110 algTcRec :: RecFlag, -- Tells whether the data type is part of
111 -- a mutually-recursive group or not
113 hasGenerics :: Bool, -- True <=> generic to/from functions are available
114 -- (in the exports of the data type's source module)
116 algTcClass :: Maybe Class
117 -- Just cl if this tycon came from a class declaration
121 tyConUnique :: Unique,
125 tyConBoxed :: Boxity,
126 tyConTyVars :: [TyVar],
132 tyConUnique :: Unique,
137 tyConTyVars :: [TyVar], -- Bound tyvars
138 synTcRhs :: Type -- Right-hand side, mentioning these type vars.
139 -- Acts as a template for the expansion when
140 -- the tycon is applied to some types.
143 | PrimTyCon { -- Primitive types; cannot be defined in Haskell
144 -- Now includes foreign-imported types
145 -- Also includes Kinds
146 tyConUnique :: Unique,
151 primTyConRep :: PrimRep,
152 -- Many primitive tycons are unboxed, but some are
153 -- boxed (represented by pointers). The CgRep tells.
155 isUnLifted :: Bool, -- Most primitive tycons are unlifted,
156 -- but foreign-imported ones may not be
157 tyConExtName :: Maybe FastString -- Just xx for foreign-imported types
160 | CoercionTyCon { -- E.g. (:=:), sym, trans, left, right
161 -- INVARIANT: coercions are always fully applied
162 tyConUnique :: Unique,
165 coKindFun :: [Type] -> Kind
168 | SuperKindTyCon { -- Super Kinds, TY (box) and CO (diamond).
169 -- They have no kind; and arity zero
170 tyConUnique :: Unique,
176 type SuperKindCon = TyCon
178 type FieldLabel = Name
181 = AbstractTyCon -- We know nothing about this data type, except
182 -- that it's represented by a pointer
183 -- Used when we export a data type abstractly into
187 data_cons :: [DataCon],
188 -- The constructors; can be empty if the user declares
189 -- the type to have no constructors
190 -- INVARIANT: Kept in order of increasing tag
191 -- (see the tag assignment in DataCon.mkDataCon)
192 is_enum :: Bool -- Cached: True <=> an enumeration type
193 } -- Includes data types with no constructors.
196 data_con :: DataCon, -- The unique constructor; it has no existentials
198 nt_rhs :: Type, -- Cached: the argument type of the constructor
199 -- = the representation type of the tycon
200 -- The free tyvars of this type are the tyConTyVars
202 nt_co :: TyCon, -- The coercion used to create the newtype
203 -- from the representation
204 -- See Note [Newtype coercions]
206 nt_etad_rhs :: ([TyVar], Type) ,
207 -- The same again, but this time eta-reduced
208 -- hence the [TyVar] which may be shorter than the declared
209 -- arity of the TyCon. See Note [Newtype eta]
211 nt_rep :: Type -- Cached: the *ultimate* representation type
212 -- By 'ultimate' I mean that the top-level constructor
213 -- of the rep type is not itself a newtype or type synonym.
214 -- The rep type isn't entirely simple:
215 -- for a recursive newtype we pick () as the rep type
218 -- This one does not need to be eta reduced; hence its
219 -- free type variables are conveniently tyConTyVars
221 -- newtype T a = MkT [(a,Int)]
222 -- The rep type is [(a,Int)]
223 -- NB: the rep type isn't necessarily the original RHS of the
224 -- newtype decl, because the rep type looks through other
227 visibleDataCons :: AlgTyConRhs -> [DataCon]
228 visibleDataCons AbstractTyCon = []
229 visibleDataCons (DataTyCon{ data_cons = cs }) = cs
230 visibleDataCons (NewTyCon{ data_con = c }) = [c]
233 Note [Newtype coercions]
234 ~~~~~~~~~~~~~~~~~~~~~~~~
236 The NewTyCon field nt_co is a a TyCon (a coercion constructor in fact)
237 which is used for coercing from the representation type of the
238 newtype, to the newtype itself. For example,
240 newtype T a = MkT [a]
242 the NewTyCon for T will contain nt_co = CoT where CoT t : [t] :=: T t.
243 This TyCon is a CoercionTyCon, so it does not have a kind on its own;
244 it basically has its own typing rule for the fully-applied version.
245 If the newtype T has k type variables then CoT has arity k.
247 In the paper we'd write
248 axiom CoT : (forall t. [t]) :=: (forall t. T t)
249 and then when we used CoT at a particular type, s, we'd say
251 which encodes as (TyConApp instCoercionTyCon [TyConApp CoT [], s])
253 But in GHC we instead make CoT into a new piece of type syntax
254 (like instCoercionTyCon, symCoercionTyCon etc), which must always
255 be saturated, but which encodes as
257 In the vocabulary of the paper it's as if we had axiom declarations
259 axiom CoT t : ([t] :=: T t)
264 newtype Parser m a = MkParser (Foogle m a)
265 Are these two types equal (to Core)?
268 Well, yes. But to see that easily we eta-reduce the RHS type of
269 Parser, in this case to ([], Froogle), so that even unsaturated applications
270 of Parser will work right. This eta reduction is done when the type
271 constructor is built, and cached in NewTyCon. The cached field is
272 only used in coreExpandTyCon_maybe.
274 Here's an example that I think showed up in practice
276 newtype T a = MkT [a]
277 newtype Foo m = MkFoo (forall a. m a -> Int)
283 w2 = MkFoo (\(MkT x) -> case w1 of MkFoo f -> f x)
285 After desugaring, and discading the data constructors for the newtypes,
289 And now Lint complains unless Foo T == Foo [], and that requires T==[]
292 %************************************************************************
296 %************************************************************************
298 A PrimRep is an abstraction of a type. It contains information that
299 the code generator needs in order to pass arguments, return results,
300 and store values of this type.
302 A PrimRep is somewhat similar to a CgRep (see codeGen/SMRep) and a
303 MachRep (see cmm/MachOp), although each of these types has a distinct
304 and clearly defined purpose:
306 - A PrimRep is a CgRep + information about signedness + information
307 about primitive pointers (AddrRep). Signedness and primitive
308 pointers are required when passing a primitive type to a foreign
309 function, but aren't needed for call/return conventions of Haskell
312 - A MachRep is a basic machine type (non-void, doesn't contain
313 information on pointerhood or signedness, but contains some
314 reps that don't have corresponding Haskell types).
320 | IntRep -- signed, word-sized
321 | WordRep -- unsinged, word-sized
322 | Int64Rep -- signed, 64 bit (32-bit words only)
323 | Word64Rep -- unsigned, 64 bit (32-bit words only)
324 | AddrRep -- a pointer, but not to a Haskell value
329 %************************************************************************
331 \subsection{TyCon Construction}
333 %************************************************************************
335 Note: the TyCon constructors all take a Kind as one argument, even though
336 they could, in principle, work out their Kind from their other arguments.
337 But to do so they need functions from Types, and that makes a nasty
338 module mutual-recursion. And they aren't called from many places.
339 So we compromise, and move their Kind calculation to the call site.
342 mkFunTyCon :: Name -> Kind -> TyCon
345 tyConUnique = nameUnique name,
351 -- This is the making of a TyCon. Just the same as the old mkAlgTyCon,
352 -- but now you also have to pass in the generic information about the type
353 -- constructor - you can get hold of it easily (see Generics module)
354 mkAlgTyCon name kind tyvars stupid rhs sel_ids is_rec gen_info gadt_syn
357 tyConUnique = nameUnique name,
359 tyConArity = length tyvars,
360 tyConTyVars = tyvars,
361 algTcStupidTheta = stupid,
363 algTcSelIds = sel_ids,
364 algTcClass = Nothing,
366 algTcGadtSyntax = gadt_syn,
367 hasGenerics = gen_info
370 mkClassTyCon name kind tyvars rhs clas is_rec
373 tyConUnique = nameUnique name,
375 tyConArity = length tyvars,
376 tyConTyVars = tyvars,
377 algTcStupidTheta = [],
380 algTcClass = Just clas,
382 algTcGadtSyntax = False, -- Doesn't really matter
387 mkTupleTyCon name kind arity tyvars con boxed gen_info
389 tyConUnique = nameUnique name,
394 tyConTyVars = tyvars,
396 hasGenerics = gen_info
399 -- Foreign-imported (.NET) type constructors are represented
400 -- as primitive, but *lifted*, TyCons for now. They are lifted
401 -- because the Haskell type T representing the (foreign) .NET
402 -- type T is actually implemented (in ILX) as a thunk<T>
403 mkForeignTyCon name ext_name kind arity
406 tyConUnique = nameUnique name,
409 primTyConRep = PtrRep, -- they all do
411 tyConExtName = ext_name
415 -- most Prim tycons are lifted
416 mkPrimTyCon name kind arity rep
417 = mkPrimTyCon' name kind arity rep True
419 mkVoidPrimTyCon name kind arity
420 = mkPrimTyCon' name kind arity VoidRep True
422 -- but RealWorld is lifted
423 mkLiftedPrimTyCon name kind arity rep
424 = mkPrimTyCon' name kind arity rep False
426 mkPrimTyCon' name kind arity rep is_unlifted
429 tyConUnique = nameUnique name,
433 isUnLifted = is_unlifted,
434 tyConExtName = Nothing
437 mkSynTyCon name kind tyvars rhs
440 tyConUnique = nameUnique name,
442 tyConArity = length tyvars,
443 tyConTyVars = tyvars,
447 mkCoercionTyCon name arity kindRule
450 tyConUnique = nameUnique name,
455 -- Super kinds always have arity zero
456 mkSuperKindTyCon name
459 tyConUnique = nameUnique name
464 isFunTyCon :: TyCon -> Bool
465 isFunTyCon (FunTyCon {}) = True
468 isAbstractTyCon :: TyCon -> Bool
469 isAbstractTyCon (AlgTyCon { algTcRhs = AbstractTyCon }) = True
470 isAbstractTyCon _ = False
472 makeTyConAbstract :: TyCon -> TyCon
473 makeTyConAbstract tc@(AlgTyCon {}) = tc { algTcRhs = AbstractTyCon }
474 makeTyConAbstract tc = pprPanic "makeTyConAbstract" (ppr tc)
476 isPrimTyCon :: TyCon -> Bool
477 isPrimTyCon (PrimTyCon {}) = True
478 isPrimTyCon _ = False
480 isUnLiftedTyCon :: TyCon -> Bool
481 isUnLiftedTyCon (PrimTyCon {isUnLifted = is_unlifted}) = is_unlifted
482 isUnLiftedTyCon (TupleTyCon {tyConBoxed = boxity}) = not (isBoxed boxity)
483 isUnLiftedTyCon _ = False
485 -- isAlgTyCon returns True for both @data@ and @newtype@
486 isAlgTyCon :: TyCon -> Bool
487 isAlgTyCon (AlgTyCon {}) = True
488 isAlgTyCon (TupleTyCon {}) = True
489 isAlgTyCon other = False
491 isDataTyCon :: TyCon -> Bool
492 -- isDataTyCon returns True for data types that are represented by
493 -- heap-allocated constructors.
494 -- These are srcutinised by Core-level @case@ expressions, and they
495 -- get info tables allocated for them.
496 -- True for all @data@ types
497 -- False for newtypes
499 isDataTyCon tc@(AlgTyCon {algTcRhs = rhs})
503 AbstractTyCon -> pprPanic "isDataTyCon" (ppr tc)
505 isDataTyCon (TupleTyCon {tyConBoxed = boxity}) = isBoxed boxity
506 isDataTyCon other = False
508 isNewTyCon :: TyCon -> Bool
509 isNewTyCon (AlgTyCon {algTcRhs = NewTyCon {}}) = True
510 isNewTyCon other = False
512 isProductTyCon :: TyCon -> Bool
514 -- has *one* constructor,
515 -- is *not* existential
517 -- may be DataType or NewType,
518 -- may be unboxed or not,
519 -- may be recursive or not
520 isProductTyCon tc@(AlgTyCon {}) = case algTcRhs tc of
521 DataTyCon{ data_cons = [data_con] }
522 -> isVanillaDataCon data_con
525 isProductTyCon (TupleTyCon {}) = True
526 isProductTyCon other = False
528 isSynTyCon :: TyCon -> Bool
529 isSynTyCon (SynTyCon {}) = True
532 isGadtSyntaxTyCon :: TyCon -> Bool
533 isGadtSyntaxTyCon (AlgTyCon { algTcGadtSyntax = res }) = res
534 isGadtSyntaxTyCon other = False
536 isEnumerationTyCon :: TyCon -> Bool
537 isEnumerationTyCon (AlgTyCon {algTcRhs = DataTyCon { is_enum = res }}) = res
538 isEnumerationTyCon other = False
540 isTupleTyCon :: TyCon -> Bool
541 -- The unit tycon didn't used to be classed as a tuple tycon
542 -- but I thought that was silly so I've undone it
543 -- If it can't be for some reason, it should be a AlgTyCon
545 -- NB: when compiling Data.Tuple, the tycons won't reply True to
546 -- isTupleTyCon, becuase they are built as AlgTyCons. However they
547 -- get spat into the interface file as tuple tycons, so I don't think
549 isTupleTyCon (TupleTyCon {}) = True
550 isTupleTyCon other = False
552 isUnboxedTupleTyCon :: TyCon -> Bool
553 isUnboxedTupleTyCon (TupleTyCon {tyConBoxed = boxity}) = not (isBoxed boxity)
554 isUnboxedTupleTyCon other = False
556 isBoxedTupleTyCon :: TyCon -> Bool
557 isBoxedTupleTyCon (TupleTyCon {tyConBoxed = boxity}) = isBoxed boxity
558 isBoxedTupleTyCon other = False
560 tupleTyConBoxity tc = tyConBoxed tc
562 isRecursiveTyCon :: TyCon -> Bool
563 isRecursiveTyCon (AlgTyCon {algTcRec = Recursive}) = True
564 isRecursiveTyCon other = False
566 isHiBootTyCon :: TyCon -> Bool
567 -- Used for knot-tying in hi-boot files
568 isHiBootTyCon (AlgTyCon {algTcRhs = AbstractTyCon}) = True
569 isHiBootTyCon other = False
571 isForeignTyCon :: TyCon -> Bool
572 -- isForeignTyCon identifies foreign-imported type constructors
573 isForeignTyCon (PrimTyCon {tyConExtName = Just _}) = True
574 isForeignTyCon other = False
576 isSuperKindTyCon :: TyCon -> Bool
577 isSuperKindTyCon (SuperKindTyCon {}) = True
578 isSuperKindTyCon other = False
580 isCoercionTyCon_maybe :: TyCon -> Maybe (Arity, [Type] -> Kind)
581 isCoercionTyCon_maybe (CoercionTyCon {tyConArity = ar, coKindFun = rule})
583 isCoercionTyCon_maybe other = Nothing
585 isCoercionTyCon (CoercionTyCon {}) = True
586 isCoercionTyCon other = False
590 -----------------------------------------------
591 -- Expand type-constructor applications
592 -----------------------------------------------
595 tcExpandTyCon_maybe, coreExpandTyCon_maybe
597 -> [Type] -- Args to tycon
598 -> Maybe ([(TyVar,Type)], -- Substitution
599 Type, -- Body type (not yet substituted)
600 [Type]) -- Leftover args
602 -- For the *typechecker* view, we expand synonyms only
603 tcExpandTyCon_maybe (SynTyCon {tyConTyVars = tvs, synTcRhs = rhs }) tys
605 tcExpandTyCon_maybe other_tycon tys = Nothing
608 -- For the *Core* view, we expand synonyms only as well
610 coreExpandTyCon_maybe (AlgTyCon {algTcRec = NonRecursive, -- Not recursive
611 algTcRhs = NewTyCon { nt_etad_rhs = etad_rhs }}) tys
612 = case etad_rhs of -- Don't do this in the pattern match, lest we accidentally
613 -- match the etad_rhs of a *recursive* newtype
614 (tvs,rhs) -> expand tvs rhs tys
616 coreExpandTyCon_maybe tycon tys = tcExpandTyCon_maybe tycon tys
619 -- For the *STG* view, we expand synonyms *and* non-recursive newtypes
620 stgExpandTyCon_maybe (AlgTyCon {algTcRec = NonRecursive, -- Not recursive
621 algTcRhs = NewTyCon { nt_etad_rhs = etad_rhs }}) tys
622 = case etad_rhs of -- Don't do this in the pattern match, lest we accidentally
623 -- match the etad_rhs of a *recursive* newtype
624 (tvs,rhs) -> expand tvs rhs tys
626 stgExpandTyCon_maybe tycon tys = coreExpandTyCon_maybe tycon tys
629 expand :: [TyVar] -> Type -- Template
631 -> Maybe ([(TyVar,Type)], Type, [Type]) -- Expansion
633 = case n_tvs `compare` length tys of
634 LT -> Just (tvs `zip` tys, rhs, drop n_tvs tys)
635 EQ -> Just (tvs `zip` tys, rhs, [])
642 tyConHasGenerics :: TyCon -> Bool
643 tyConHasGenerics (AlgTyCon {hasGenerics = hg}) = hg
644 tyConHasGenerics (TupleTyCon {hasGenerics = hg}) = hg
645 tyConHasGenerics other = False -- Synonyms
647 tyConDataCons :: TyCon -> [DataCon]
648 -- It's convenient for tyConDataCons to return the
649 -- empty list for type synonyms etc
650 tyConDataCons tycon = tyConDataCons_maybe tycon `orElse` []
652 tyConDataCons_maybe :: TyCon -> Maybe [DataCon]
653 tyConDataCons_maybe (AlgTyCon {algTcRhs = DataTyCon { data_cons = cons }}) = Just cons
654 tyConDataCons_maybe (AlgTyCon {algTcRhs = NewTyCon { data_con = con }}) = Just [con]
655 tyConDataCons_maybe (TupleTyCon {dataCon = con}) = Just [con]
656 tyConDataCons_maybe other = Nothing
658 tyConFamilySize :: TyCon -> Int
659 tyConFamilySize (AlgTyCon {algTcRhs = DataTyCon { data_cons = cons }}) = length cons
660 tyConFamilySize (AlgTyCon {algTcRhs = NewTyCon {}}) = 1
661 tyConFamilySize (TupleTyCon {}) = 1
663 tyConFamilySize other = pprPanic "tyConFamilySize:" (ppr other)
666 tyConSelIds :: TyCon -> [Id]
667 tyConSelIds (AlgTyCon {algTcSelIds = fs}) = fs
668 tyConSelIds other_tycon = []
670 algTyConRhs :: TyCon -> AlgTyConRhs
671 algTyConRhs (AlgTyCon {algTcRhs = rhs}) = rhs
672 algTyConRhs (TupleTyCon {dataCon = con}) = DataTyCon { data_cons = [con], is_enum = False }
673 algTyConRhs other = pprPanic "algTyConRhs" (ppr other)
677 newTyConRhs :: TyCon -> ([TyVar], Type)
678 newTyConRhs (AlgTyCon {tyConTyVars = tvs, algTcRhs = NewTyCon { nt_rhs = rhs }}) = (tvs, rhs)
679 newTyConRhs tycon = pprPanic "newTyConRhs" (ppr tycon)
681 newTyConRep :: TyCon -> ([TyVar], Type)
682 newTyConRep (AlgTyCon {tyConTyVars = tvs, algTcRhs = NewTyCon { nt_rep = rep }}) = (tvs, rep)
683 newTyConRep tycon = pprPanic "newTyConRep" (ppr tycon)
685 newTyConCo :: TyCon -> TyCon
686 newTyConCo (AlgTyCon {tyConTyVars = tvs, algTcRhs = NewTyCon { nt_co = co }}) = co
687 newTyConCo tycon = pprPanic "newTyConCo" (ppr tycon)
689 tyConPrimRep :: TyCon -> PrimRep
690 tyConPrimRep (PrimTyCon {primTyConRep = rep}) = rep
691 tyConPrimRep tc = ASSERT(not (isUnboxedTupleTyCon tc)) PtrRep
695 tyConStupidTheta :: TyCon -> [PredType]
696 tyConStupidTheta (AlgTyCon {algTcStupidTheta = stupid}) = stupid
697 tyConStupidTheta (TupleTyCon {}) = []
698 tyConStupidTheta tycon = pprPanic "tyConStupidTheta" (ppr tycon)
702 synTyConDefn :: TyCon -> ([TyVar], Type)
703 synTyConDefn (SynTyCon {tyConTyVars = tyvars, synTcRhs = ty}) = (tyvars,ty)
704 synTyConDefn tycon = pprPanic "getSynTyConDefn" (ppr tycon)
706 synTyConRhs :: TyCon -> Type
707 synTyConRhs tc = synTcRhs tc
711 maybeTyConSingleCon :: TyCon -> Maybe DataCon
712 maybeTyConSingleCon (AlgTyCon {algTcRhs = DataTyCon {data_cons = [c] }}) = Just c
713 maybeTyConSingleCon (AlgTyCon {algTcRhs = NewTyCon { data_con = c }}) = Just c
714 maybeTyConSingleCon (AlgTyCon {}) = Nothing
715 maybeTyConSingleCon (TupleTyCon {dataCon = con}) = Just con
716 maybeTyConSingleCon (PrimTyCon {}) = Nothing
717 maybeTyConSingleCon (FunTyCon {}) = Nothing -- case at funty
718 maybeTyConSingleCon tc = pprPanic "maybeTyConSingleCon: unexpected tycon " $ ppr tc
722 isClassTyCon :: TyCon -> Bool
723 isClassTyCon (AlgTyCon {algTcClass = Just _}) = True
724 isClassTyCon other_tycon = False
726 tyConClass_maybe :: TyCon -> Maybe Class
727 tyConClass_maybe (AlgTyCon {algTcClass = maybe_clas}) = maybe_clas
728 tyConClass_maybe ther_tycon = Nothing
732 %************************************************************************
734 \subsection[TyCon-instances]{Instance declarations for @TyCon@}
736 %************************************************************************
738 @TyCon@s are compared by comparing their @Unique@s.
740 The strictness analyser needs @Ord@. It is a lexicographic order with
741 the property @(a<=b) || (b<=a)@.
744 instance Eq TyCon where
745 a == b = case (a `compare` b) of { EQ -> True; _ -> False }
746 a /= b = case (a `compare` b) of { EQ -> False; _ -> True }
748 instance Ord TyCon where
749 a <= b = case (a `compare` b) of { LT -> True; EQ -> True; GT -> False }
750 a < b = case (a `compare` b) of { LT -> True; EQ -> False; GT -> False }
751 a >= b = case (a `compare` b) of { LT -> False; EQ -> True; GT -> True }
752 a > b = case (a `compare` b) of { LT -> False; EQ -> False; GT -> True }
753 compare a b = getUnique a `compare` getUnique b
755 instance Uniquable TyCon where
756 getUnique tc = tyConUnique tc
758 instance Outputable TyCon where
759 ppr tc = ppr (getName tc)
761 instance NamedThing TyCon where