Fixed warnings in hsSyn/HsImpExp, except for incomplete pattern matches
[ghc-hetmet.git] / compiler / prelude / TysWiredIn.lhs
1 %
2 % (c) The GRASP Project, Glasgow University, 1994-1998
3 %
4 \section[TysWiredIn]{Wired-in knowledge about {\em non-primitive} types}
5
6 This module is about types that can be defined in Haskell, but which
7 must be wired into the compiler nonetheless.
8
9 This module tracks the ``state interface'' document, ``GHC prelude:
10 types and operations.''
11
12 \begin{code}
13 {-# OPTIONS -w #-}
14 -- The above warning supression flag is a temporary kludge.
15 -- While working on this module you are encouraged to remove it and fix
16 -- any warnings in the module. See
17 --     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
18 -- for details
19
20 module TysWiredIn (
21         wiredInTyCons, 
22
23         boolTy, boolTyCon, boolTyCon_RDR, boolTyConName,
24         trueDataCon,  trueDataConId,  true_RDR,
25         falseDataCon, falseDataConId, false_RDR,
26
27         charTyCon, charDataCon, charTyCon_RDR,
28         charTy, stringTy, charTyConName,
29
30         
31         doubleTyCon, doubleDataCon, doubleTy, doubleTyConName, 
32         
33         floatTyCon, floatDataCon, floatTy, floatTyConName,
34
35         intTyCon, intDataCon, intTyCon_RDR, intDataCon_RDR, intTyConName,
36         intTy,
37
38         listTyCon, nilDataCon, consDataCon,
39         listTyCon_RDR, consDataCon_RDR, listTyConName,
40         mkListTy,
41
42         -- tuples
43         mkTupleTy,
44         tupleTyCon, tupleCon, 
45         unitTyCon, unitDataCon, unitDataConId, pairTyCon, 
46         unboxedSingletonTyCon, unboxedSingletonDataCon,
47         unboxedPairTyCon, unboxedPairDataCon,
48        
49         boxedTupleArr, unboxedTupleArr,
50
51         unitTy,
52
53         -- parallel arrays
54         mkPArrTy,
55         parrTyCon, parrFakeCon, isPArrTyCon, isPArrFakeCon,
56         parrTyCon_RDR, parrTyConName
57     ) where
58
59 #include "HsVersions.h"
60
61 import {-# SOURCE #-} MkId( mkDataConIds )
62
63 -- friends:
64 import PrelNames
65 import TysPrim
66
67 -- others:
68 import Constants        ( mAX_TUPLE_SIZE )
69 import Module           ( Module )
70 import RdrName          ( nameRdrName )
71 import Name             ( Name, BuiltInSyntax(..), nameUnique, nameOccName, 
72                           nameModule, mkWiredInName )
73 import OccName          ( mkOccNameFS, tcName, dataName, mkTupleOcc,
74                           mkDataConWorkerOcc )
75 import DataCon          ( DataCon, mkDataCon, dataConWorkId, dataConSourceArity )
76 import Var              ( TyVar, tyVarKind )
77 import TyCon            ( TyCon, AlgTyConRhs(DataTyCon), tyConDataCons,
78                           mkTupleTyCon, mkAlgTyCon, tyConName,
79                           TyConParent(NoParentTyCon) )
80
81 import BasicTypes       ( Arity, RecFlag(..), Boxity(..), isBoxed,
82                           StrictnessMark(..) )
83
84 import Type             ( Type, mkTyConTy, mkTyConApp, mkTyVarTy, mkTyVarTys,
85                           TyThing(..) )
86 import Coercion         ( unsafeCoercionTyCon, symCoercionTyCon,
87                           transCoercionTyCon, leftCoercionTyCon, 
88                           rightCoercionTyCon, instCoercionTyCon )
89 import TypeRep          ( mkArrowKinds, liftedTypeKind, ubxTupleKind )
90 import Unique           ( incrUnique, mkTupleTyConUnique,
91                           mkTupleDataConUnique, mkPArrDataConUnique )
92 import Array
93 import FastString
94 import Outputable
95
96 alpha_tyvar = [alphaTyVar]
97 alpha_ty    = [alphaTy]
98 \end{code}
99
100
101 %************************************************************************
102 %*                                                                      *
103 \subsection{Wired in type constructors}
104 %*                                                                      *
105 %************************************************************************
106
107 If you change which things are wired in, make sure you change their
108 names in PrelNames, so they use wTcQual, wDataQual, etc
109
110 \begin{code}
111 wiredInTyCons :: [TyCon]        -- Excludes tuples
112 -- This list is used only to define PrelInfo.wiredInThings
113
114 -- It does not need to include kind constructors, because
115 -- all that wiredInThings does is to initialise the Name table,
116 -- and kind constructors don't appear in source code.
117
118 wiredInTyCons = [ unitTyCon     -- Not treated like other tuples, because
119                                 -- it's defined in GHC.Base, and there's only
120                                 -- one of it.  We put it in wiredInTyCons so
121                                 -- that it'll pre-populate the name cache, so
122                                 -- the special case in lookupOrigNameCache 
123                                 -- doesn't need to look out for it
124               , boolTyCon
125               , charTyCon
126               , doubleTyCon
127               , floatTyCon
128               , intTyCon
129               , listTyCon
130               , parrTyCon
131               , unsafeCoercionTyCon
132               , symCoercionTyCon
133               , transCoercionTyCon
134               , leftCoercionTyCon
135               , rightCoercionTyCon
136               , instCoercionTyCon
137               ]
138 \end{code}
139
140 \begin{code}
141 mkWiredInTyConName :: BuiltInSyntax -> Module -> FastString -> Unique -> TyCon -> Name
142 mkWiredInTyConName built_in mod fs uniq tycon
143   = mkWiredInName mod (mkOccNameFS tcName fs) uniq
144                   (ATyCon tycon)        -- Relevant TyCon
145                   built_in
146
147 mkWiredInDataConName :: BuiltInSyntax -> Module -> FastString -> Unique -> DataCon -> Name
148 mkWiredInDataConName built_in mod fs uniq datacon
149   = mkWiredInName mod (mkOccNameFS dataName fs) uniq
150                   (ADataCon datacon)    -- Relevant DataCon
151                   built_in
152
153 charTyConName     = mkWiredInTyConName   UserSyntax gHC_BASE FSLIT("Char") charTyConKey charTyCon
154 charDataConName   = mkWiredInDataConName UserSyntax gHC_BASE FSLIT("C#") charDataConKey charDataCon
155 intTyConName      = mkWiredInTyConName   UserSyntax gHC_BASE FSLIT("Int") intTyConKey   intTyCon
156 intDataConName    = mkWiredInDataConName UserSyntax gHC_BASE FSLIT("I#") intDataConKey  intDataCon
157                                                   
158 boolTyConName     = mkWiredInTyConName   UserSyntax gHC_BASE FSLIT("Bool") boolTyConKey boolTyCon
159 falseDataConName  = mkWiredInDataConName UserSyntax gHC_BASE FSLIT("False") falseDataConKey falseDataCon
160 trueDataConName   = mkWiredInDataConName UserSyntax gHC_BASE FSLIT("True")  trueDataConKey  trueDataCon 
161 listTyConName     = mkWiredInTyConName   BuiltInSyntax gHC_BASE FSLIT("[]") listTyConKey listTyCon
162 nilDataConName    = mkWiredInDataConName BuiltInSyntax gHC_BASE FSLIT("[]") nilDataConKey nilDataCon 
163 consDataConName   = mkWiredInDataConName BuiltInSyntax gHC_BASE FSLIT(":") consDataConKey consDataCon
164
165 floatTyConName     = mkWiredInTyConName   UserSyntax gHC_FLOAT FSLIT("Float") floatTyConKey floatTyCon
166 floatDataConName   = mkWiredInDataConName UserSyntax gHC_FLOAT FSLIT("F#") floatDataConKey floatDataCon
167 doubleTyConName    = mkWiredInTyConName   UserSyntax gHC_FLOAT FSLIT("Double") doubleTyConKey doubleTyCon
168 doubleDataConName  = mkWiredInDataConName UserSyntax gHC_FLOAT FSLIT("D#") doubleDataConKey doubleDataCon
169
170 parrTyConName     = mkWiredInTyConName   BuiltInSyntax gHC_PARR FSLIT("[::]") parrTyConKey parrTyCon 
171 parrDataConName   = mkWiredInDataConName UserSyntax    gHC_PARR FSLIT("PArr") parrDataConKey parrDataCon
172
173 boolTyCon_RDR   = nameRdrName boolTyConName
174 false_RDR       = nameRdrName falseDataConName
175 true_RDR        = nameRdrName trueDataConName
176 intTyCon_RDR    = nameRdrName intTyConName
177 charTyCon_RDR   = nameRdrName charTyConName
178 intDataCon_RDR  = nameRdrName intDataConName
179 listTyCon_RDR   = nameRdrName listTyConName
180 consDataCon_RDR = nameRdrName consDataConName
181 parrTyCon_RDR   = nameRdrName parrTyConName
182 {-
183 tySuperKindTyCon_RDR     = nameRdrName tySuperKindTyConName
184 coSuperKindTyCon_RDR = nameRdrName coSuperKindTyConName
185 liftedTypeKindTyCon_RDR   = nameRdrName liftedTypeKindTyConName
186 openTypeKindTyCon_RDR     = nameRdrName openTypeKindTyConName
187 unliftedTypeKindTyCon_RDR = nameRdrName unliftedTypeKindTyConName
188 ubxTupleKindTyCon_RDR     = nameRdrName ubxTupleKindTyConName
189 argTypeKindTyCon_RDR      = nameRdrName argTypeKindTyConName
190 funKindTyCon_RDR          = nameRdrName funKindTyConName
191 -}
192 \end{code}
193
194
195 %************************************************************************
196 %*                                                                      *
197 \subsection{mkWiredInTyCon}
198 %*                                                                      *
199 %************************************************************************
200
201 \begin{code}
202 pcNonRecDataTyCon = pcTyCon False NonRecursive
203 pcRecDataTyCon    = pcTyCon False Recursive
204
205 pcTyCon is_enum is_rec name tyvars cons
206   = tycon
207   where
208     tycon = mkAlgTyCon name
209                 (mkArrowKinds (map tyVarKind tyvars) liftedTypeKind)
210                 tyvars
211                 []              -- No stupid theta
212                 (DataTyCon cons is_enum)
213                 []              -- No record selectors
214                 NoParentTyCon
215                 is_rec
216                 True            -- All the wired-in tycons have generics
217                 False           -- Not in GADT syntax
218
219 pcDataCon :: Name -> [TyVar] -> [Type] -> TyCon -> DataCon
220 pcDataCon = pcDataConWithFixity False
221
222 pcDataConWithFixity :: Bool -> Name -> [TyVar] -> [Type] -> TyCon -> DataCon
223 -- The Name should be in the DataName name space; it's the name
224 -- of the DataCon itself.
225 --
226 -- The unique is the first of two free uniques;
227 -- the first is used for the datacon itself,
228 -- the second is used for the "worker name"
229
230 pcDataConWithFixity declared_infix dc_name tyvars arg_tys tycon
231   = data_con
232   where
233     data_con = mkDataCon dc_name declared_infix
234                 (map (const NotMarkedStrict) arg_tys)
235                 []      -- No labelled fields
236                 tyvars
237                 []      -- No existential type variables
238                 []      -- No equality spec
239                 []      -- No theta
240                 arg_tys tycon
241                 []      -- No stupid theta
242                 (mkDataConIds bogus_wrap_name wrk_name data_con)
243                 
244
245     mod      = nameModule dc_name
246     wrk_occ  = mkDataConWorkerOcc (nameOccName dc_name)
247     wrk_key  = incrUnique (nameUnique dc_name)
248     wrk_name = mkWiredInName mod wrk_occ wrk_key
249                              (AnId (dataConWorkId data_con)) UserSyntax
250     bogus_wrap_name = pprPanic "Wired-in data wrapper id" (ppr dc_name)
251         -- Wired-in types are too simple to need wrappers
252 \end{code}
253
254
255 %************************************************************************
256 %*                                                                      *
257 \subsection[TysWiredIn-tuples]{The tuple types}
258 %*                                                                      *
259 %************************************************************************
260
261 \begin{code}
262 tupleTyCon :: Boxity -> Arity -> TyCon
263 tupleTyCon boxity i | i > mAX_TUPLE_SIZE = fst (mk_tuple boxity i)      -- Build one specially
264 tupleTyCon Boxed   i = fst (boxedTupleArr   ! i)
265 tupleTyCon Unboxed i = fst (unboxedTupleArr ! i)
266
267 tupleCon :: Boxity -> Arity -> DataCon
268 tupleCon boxity i | i > mAX_TUPLE_SIZE = snd (mk_tuple boxity i)        -- Build one specially
269 tupleCon Boxed   i = snd (boxedTupleArr   ! i)
270 tupleCon Unboxed i = snd (unboxedTupleArr ! i)
271
272 boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
273 boxedTupleArr   = listArray (0,mAX_TUPLE_SIZE) [mk_tuple Boxed i | i <- [0..mAX_TUPLE_SIZE]]
274 unboxedTupleArr = listArray (0,mAX_TUPLE_SIZE) [mk_tuple Unboxed i | i <- [0..mAX_TUPLE_SIZE]]
275
276 mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
277 mk_tuple boxity arity = (tycon, tuple_con)
278   where
279         tycon   = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con boxity gen_info 
280         mod     = mkTupleModule boxity arity
281         tc_name = mkWiredInName mod (mkTupleOcc tcName boxity arity) tc_uniq
282                                 (ATyCon tycon) BuiltInSyntax
283         tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
284         res_kind | isBoxed boxity = liftedTypeKind
285                  | otherwise      = ubxTupleKind
286
287         tyvars   | isBoxed boxity = take arity alphaTyVars
288                  | otherwise      = take arity openAlphaTyVars
289
290         tuple_con = pcDataCon dc_name tyvars tyvar_tys tycon
291         tyvar_tys = mkTyVarTys tyvars
292         dc_name   = mkWiredInName mod (mkTupleOcc dataName boxity arity) dc_uniq
293                                   (ADataCon tuple_con) BuiltInSyntax
294         tc_uniq   = mkTupleTyConUnique   boxity arity
295         dc_uniq   = mkTupleDataConUnique boxity arity
296         gen_info  = True                -- Tuples all have generics..
297                                         -- hmm: that's a *lot* of code
298
299 unitTyCon     = tupleTyCon Boxed 0
300 unitDataCon   = head (tyConDataCons unitTyCon)
301 unitDataConId = dataConWorkId unitDataCon
302
303 pairTyCon = tupleTyCon Boxed 2
304
305 unboxedSingletonTyCon   = tupleTyCon Unboxed 1
306 unboxedSingletonDataCon = tupleCon   Unboxed 1
307
308 unboxedPairTyCon   = tupleTyCon Unboxed 2
309 unboxedPairDataCon = tupleCon   Unboxed 2
310 \end{code}
311
312 %************************************************************************
313 %*                                                                      *
314 \subsection[TysWiredIn-boxed-prim]{The ``boxed primitive'' types (@Char@, @Int@, etc)}
315 %*                                                                      *
316 %************************************************************************
317
318 \begin{code}
319 charTy = mkTyConTy charTyCon
320
321 charTyCon   = pcNonRecDataTyCon charTyConName [] [charDataCon]
322 charDataCon = pcDataCon charDataConName [] [charPrimTy] charTyCon
323
324 stringTy = mkListTy charTy -- convenience only
325 \end{code}
326
327 \begin{code}
328 intTy = mkTyConTy intTyCon 
329
330 intTyCon = pcNonRecDataTyCon intTyConName [] [intDataCon]
331 intDataCon = pcDataCon intDataConName [] [intPrimTy] intTyCon
332 \end{code}
333
334 \begin{code}
335 floatTy = mkTyConTy floatTyCon
336
337 floatTyCon   = pcNonRecDataTyCon floatTyConName   [] [floatDataCon]
338 floatDataCon = pcDataCon         floatDataConName [] [floatPrimTy] floatTyCon
339 \end{code}
340
341 \begin{code}
342 doubleTy = mkTyConTy doubleTyCon
343
344 doubleTyCon   = pcNonRecDataTyCon doubleTyConName   [] [doubleDataCon]
345 doubleDataCon = pcDataCon         doubleDataConName [] [doublePrimTy] doubleTyCon
346 \end{code}
347
348
349 %************************************************************************
350 %*                                                                      *
351 \subsection[TysWiredIn-Bool]{The @Bool@ type}
352 %*                                                                      *
353 %************************************************************************
354
355 An ordinary enumeration type, but deeply wired in.  There are no
356 magical operations on @Bool@ (just the regular Prelude code).
357
358 {\em BEGIN IDLE SPECULATION BY SIMON}
359
360 This is not the only way to encode @Bool@.  A more obvious coding makes
361 @Bool@ just a boxed up version of @Bool#@, like this:
362 \begin{verbatim}
363 type Bool# = Int#
364 data Bool = MkBool Bool#
365 \end{verbatim}
366
367 Unfortunately, this doesn't correspond to what the Report says @Bool@
368 looks like!  Furthermore, we get slightly less efficient code (I
369 think) with this coding. @gtInt@ would look like this:
370
371 \begin{verbatim}
372 gtInt :: Int -> Int -> Bool
373 gtInt x y = case x of I# x# ->
374             case y of I# y# ->
375             case (gtIntPrim x# y#) of
376                 b# -> MkBool b#
377 \end{verbatim}
378
379 Notice that the result of the @gtIntPrim@ comparison has to be turned
380 into an integer (here called @b#@), and returned in a @MkBool@ box.
381
382 The @if@ expression would compile to this:
383 \begin{verbatim}
384 case (gtInt x y) of
385   MkBool b# -> case b# of { 1# -> e1; 0# -> e2 }
386 \end{verbatim}
387
388 I think this code is a little less efficient than the previous code,
389 but I'm not certain.  At all events, corresponding with the Report is
390 important.  The interesting thing is that the language is expressive
391 enough to describe more than one alternative; and that a type doesn't
392 necessarily need to be a straightforwardly boxed version of its
393 primitive counterpart.
394
395 {\em END IDLE SPECULATION BY SIMON}
396
397 \begin{code}
398 boolTy = mkTyConTy boolTyCon
399
400 boolTyCon = pcTyCon True NonRecursive boolTyConName
401                     [] [falseDataCon, trueDataCon]
402
403 falseDataCon = pcDataCon falseDataConName [] [] boolTyCon
404 trueDataCon  = pcDataCon trueDataConName  [] [] boolTyCon
405
406 falseDataConId = dataConWorkId falseDataCon
407 trueDataConId  = dataConWorkId trueDataCon
408 \end{code}
409
410 %************************************************************************
411 %*                                                                      *
412 \subsection[TysWiredIn-List]{The @List@ type (incl ``build'' magic)}
413 %*                                                                      *
414 %************************************************************************
415
416 Special syntax, deeply wired in, but otherwise an ordinary algebraic
417 data types:
418 \begin{verbatim}
419 data [] a = [] | a : (List a)
420 data () = ()
421 data (,) a b = (,,) a b
422 ...
423 \end{verbatim}
424
425 \begin{code}
426 mkListTy :: Type -> Type
427 mkListTy ty = mkTyConApp listTyCon [ty]
428
429 listTyCon = pcRecDataTyCon listTyConName alpha_tyvar [nilDataCon, consDataCon]
430
431 nilDataCon  = pcDataCon nilDataConName alpha_tyvar [] listTyCon
432 consDataCon = pcDataConWithFixity True {- Declared infix -}
433                consDataConName
434                alpha_tyvar [alphaTy, mkTyConApp listTyCon alpha_ty] listTyCon
435 -- Interesting: polymorphic recursion would help here.
436 -- We can't use (mkListTy alphaTy) in the defn of consDataCon, else mkListTy
437 -- gets the over-specific type (Type -> Type)
438 \end{code}
439
440 %************************************************************************
441 %*                                                                      *
442 \subsection[TysWiredIn-Tuples]{The @Tuple@ types}
443 %*                                                                      *
444 %************************************************************************
445
446 The tuple types are definitely magic, because they form an infinite
447 family.
448
449 \begin{itemize}
450 \item
451 They have a special family of type constructors, of type @TyCon@
452 These contain the tycon arity, but don't require a Unique.
453
454 \item
455 They have a special family of constructors, of type
456 @Id@. Again these contain their arity but don't need a Unique.
457
458 \item
459 There should be a magic way of generating the info tables and
460 entry code for all tuples.
461
462 But at the moment we just compile a Haskell source
463 file\srcloc{lib/prelude/...} containing declarations like:
464 \begin{verbatim}
465 data Tuple0             = Tup0
466 data Tuple2  a b        = Tup2  a b
467 data Tuple3  a b c      = Tup3  a b c
468 data Tuple4  a b c d    = Tup4  a b c d
469 ...
470 \end{verbatim}
471 The print-names associated with the magic @Id@s for tuple constructors
472 ``just happen'' to be the same as those generated by these
473 declarations.
474
475 \item
476 The instance environment should have a magic way to know
477 that each tuple type is an instances of classes @Eq@, @Ix@, @Ord@ and
478 so on. \ToDo{Not implemented yet.}
479
480 \item
481 There should also be a way to generate the appropriate code for each
482 of these instances, but (like the info tables and entry code) it is
483 done by enumeration\srcloc{lib/prelude/InTup?.hs}.
484 \end{itemize}
485
486 \begin{code}
487 mkTupleTy :: Boxity -> Int -> [Type] -> Type
488 mkTupleTy boxity arity tys = mkTyConApp (tupleTyCon boxity arity) tys
489
490 unitTy = mkTupleTy Boxed 0 []
491 \end{code}
492
493 %************************************************************************
494 %*                                                                      *
495 \subsection[TysWiredIn-PArr]{The @[::]@ type}
496 %*                                                                      *
497 %************************************************************************
498
499 Special syntax for parallel arrays needs some wired in definitions.
500
501 \begin{code}
502 -- construct a type representing the application of the parallel array
503 -- constructor 
504 --
505 mkPArrTy    :: Type -> Type
506 mkPArrTy ty  = mkTyConApp parrTyCon [ty]
507
508 -- represents the type constructor of parallel arrays
509 --
510 --  * this must match the definition in `PrelPArr'
511 --
512 -- NB: Although the constructor is given here, it will not be accessible in
513 --     user code as it is not in the environment of any compiled module except
514 --     `PrelPArr'.
515 --
516 parrTyCon :: TyCon
517 parrTyCon  = pcNonRecDataTyCon parrTyConName alpha_tyvar [parrDataCon]
518
519 parrDataCon :: DataCon
520 parrDataCon  = pcDataCon 
521                  parrDataConName 
522                  alpha_tyvar            -- forall'ed type variables
523                  [intPrimTy,            -- 1st argument: Int#
524                   mkTyConApp            -- 2nd argument: Array# a
525                     arrayPrimTyCon 
526                     alpha_ty] 
527                  parrTyCon
528
529 -- check whether a type constructor is the constructor for parallel arrays
530 --
531 isPArrTyCon    :: TyCon -> Bool
532 isPArrTyCon tc  = tyConName tc == parrTyConName
533
534 -- fake array constructors
535 --
536 --  * these constructors are never really used to represent array values;
537 --   however, they are very convenient during desugaring (and, in particular,
538 --   in the pattern matching compiler) to treat array pattern just like
539 --   yet another constructor pattern
540 --
541 parrFakeCon                        :: Arity -> DataCon
542 parrFakeCon i | i > mAX_TUPLE_SIZE  = mkPArrFakeCon  i  -- build one specially
543 parrFakeCon i                       = parrFakeConArr!i
544
545 -- pre-defined set of constructors
546 --
547 parrFakeConArr :: Array Int DataCon
548 parrFakeConArr  = array (0, mAX_TUPLE_SIZE) [(i, mkPArrFakeCon i)   
549                                             | i <- [0..mAX_TUPLE_SIZE]]
550
551 -- build a fake parallel array constructor for the given arity
552 --
553 mkPArrFakeCon       :: Int -> DataCon
554 mkPArrFakeCon arity  = data_con
555   where
556         data_con  = pcDataCon name [tyvar] tyvarTys parrTyCon
557         tyvar     = head alphaTyVars
558         tyvarTys  = replicate arity $ mkTyVarTy tyvar
559         nameStr   = mkFastString ("MkPArr" ++ show arity)
560         name      = mkWiredInName gHC_PARR (mkOccNameFS dataName nameStr) uniq
561                                   (ADataCon data_con) UserSyntax
562         uniq      = mkPArrDataConUnique arity
563
564 -- checks whether a data constructor is a fake constructor for parallel arrays
565 --
566 isPArrFakeCon      :: DataCon -> Bool
567 isPArrFakeCon dcon  = dcon == parrFakeCon (dataConSourceArity dcon)
568 \end{code}
569
570