[project @ 1996-12-19 18:35:23 by simonpj]
[ghc-hetmet.git] / ghc / lib / ghc / PrelBase.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 \section[PrelBase]{Module @PrelBase@}
5
6
7 \begin{code}
8 module PrelBase where
9
10 import Prelude ()
11 import IOBase   ( error )       {-# SOURCE #-}
12 import GHC
13
14 infixr 9  ., !!
15 infixl 7  *, /
16 infixl 6  +, -
17 infixr 5  ++, :
18 infix  4  ==, /=, <, <=, >=, >
19 infixr 3  &&
20 infixr 2  ||
21 infixr 1  >>, >>=
22 infixr 0  $
23 \end{code}
24
25 %*********************************************************
26 %*                                                      *
27 \subsection{Standard classes @Eq@, @Ord@, @Bounded@, @Eval@}
28 %*                                                      *
29 %*********************************************************
30
31 \begin{code}
32 class  Eq a  where
33     (==), (/=)          :: a -> a -> Bool
34
35     x /= y              =  not (x == y)
36
37 class  (Eq a) => Ord a  where
38     compare             :: a -> a -> Ordering
39     (<), (<=), (>=), (>):: a -> a -> Bool
40     max, min            :: a -> a -> a
41
42 -- An instance of Ord should define either compare or <=
43 -- Using compare can be more efficient for complex types.
44     compare x y
45             | x == y    = EQ
46             | x <= y    = LT
47             | otherwise = GT
48
49     x <= y  = compare x y /= GT
50     x <  y  = compare x y == LT
51     x >= y  = compare x y /= LT
52     x >  y  = compare x y == GT
53     max x y = case (compare x y) of { LT -> y ; EQ -> x ; GT -> x }
54     min x y = case (compare x y) of { LT -> x ; EQ -> x ; GT -> y }
55
56 class  Bounded a  where
57     minBound, maxBound :: a
58
59 class Eval a
60 \end{code}
61
62 %*********************************************************
63 %*                                                      *
64 \subsection{Monadic classes @Functor@, @Monad@, @MonadZero@, @MonadPlus@}
65 %*                                                      *
66 %*********************************************************
67
68 \begin{code}
69 class  Functor f  where
70     map         :: (a -> b) -> f a -> f b
71
72 class  Monad m  where
73     (>>=)       :: m a -> (a -> m b) -> m b
74     (>>)        :: m a -> m b -> m b
75     return      :: a -> m a
76
77     m >> k      =  m >>= \_ -> k
78
79 class  (Monad m) => MonadZero m  where
80     zero        :: m a
81
82 class  (MonadZero m) => MonadPlus m where
83    (++)         :: m a -> m a -> m a
84 \end{code}
85
86
87 %*********************************************************
88 %*                                                      *
89 \subsection{Classes @Num@ and @Enum@}
90 %*                                                      *
91 %*********************************************************
92
93 \begin{code}
94 class  (Ord a) => Enum a        where
95     toEnum              :: Int -> a
96     fromEnum            :: a -> Int
97     enumFrom            :: a -> [a]             -- [n..]
98     enumFromThen        :: a -> a -> [a]        -- [n,n'..]
99     enumFromTo          :: a -> a -> [a]        -- [n..m]
100     enumFromThenTo      :: a -> a -> a -> [a]   -- [n,n'..m]
101
102     enumFromTo n m      =  takeWhile (<= m) (enumFrom n)
103     enumFromThenTo n n' m
104                         =  takeWhile (if n' >= n then (<= m) else (>= m))
105                                      (enumFromThen n n')
106
107 class  (Eq a, Show a, Eval a) => Num a  where
108     (+), (-), (*)       :: a -> a -> a
109     negate              :: a -> a
110     abs, signum         :: a -> a
111     fromInteger         :: Integer -> a
112     fromInt             :: Int -> a -- partain: Glasgow extension
113
114     x - y               =  x + negate y
115     fromInt (I# i#)     = fromInteger (int2Integer# i#)
116                                         -- Go via the standard class-op if the
117                                         -- non-standard one ain't provided
118 \end{code}
119
120 \begin{code}
121 succ, pred              :: Enum a => a -> a
122 succ                    =  toEnum . (+1) . fromEnum
123 pred                    =  toEnum . (subtract 1) . fromEnum
124
125 chr = (toEnum   :: Int  -> Char)
126 ord = (fromEnum :: Char -> Int)
127
128 ord_0 :: Num a => a
129 ord_0 = fromInt (ord '0')
130
131 {-# GENERATE_SPECS subtract a{Int#,Double#,Int,Double,Complex(Double#),Complex(Double)} #-}
132 subtract        :: (Num a) => a -> a -> a
133 subtract x y    =  y - x
134 \end{code}
135
136
137 %*********************************************************
138 %*                                                      *
139 \subsection{The @Show@ class}
140 %*                                                      *
141 %*********************************************************
142
143 \begin{code}
144 type  ShowS     = String -> String
145
146 class  Show a  where
147     showsPrec :: Int -> a -> ShowS
148     showList  :: [a] -> ShowS
149
150     showList [] = showString "[]"
151     showList (x:xs)
152                 = showChar '[' . shows x . showl xs
153                   where showl []     = showChar ']'
154                         showl (x:xs) = showString ", " . shows x . showl xs
155 \end{code}
156
157 %*********************************************************
158 %*                                                      *
159 \subsection{The list type}
160 %*                                                      *
161 %*********************************************************
162
163 \begin{code}
164 data [] a = [] | a : [a]  -- do explicitly: deriving (Eq, Ord)
165                           -- to avoid weird names like con2tag_[]#
166
167 instance (Eq a) => Eq [a]  where
168     []     == []     = True     
169     (x:xs) == (y:ys) = x == y && xs == ys
170     []     == ys     = False                    
171     xs     == []     = False                    
172     xs     /= ys     = if (xs == ys) then False else True
173
174 instance (Ord a) => Ord [a] where
175     a <  b  = case compare a b of { LT -> True;  EQ -> False; GT -> False }
176     a <= b  = case compare a b of { LT -> True;  EQ -> True;  GT -> False }
177     a >= b  = case compare a b of { LT -> False; EQ -> True;  GT -> True  }
178     a >  b  = case compare a b of { LT -> False; EQ -> False; GT -> True  }
179
180     max a b = case compare a b of { LT -> b; EQ -> a;  GT -> a }
181     min a b = case compare a b of { LT -> a; EQ -> a;  GT -> b }
182
183     compare []     []     = EQ
184     compare (x:xs) []     = GT
185     compare []     (y:ys) = LT
186     compare (x:xs) (y:ys) = case compare x y of
187                                  LT -> LT       
188                                  GT -> GT               
189                                  EQ -> compare xs ys
190
191 instance Functor [] where
192     map f []             =  []
193     map f (x:xs)         =  f x : map f xs
194
195 instance  Monad []  where
196     m >>= k             = foldr ((++) . k) [] m
197     return x            = [x]
198
199 instance  MonadZero []  where
200     zero                = []
201
202 instance  MonadPlus []  where
203     xs ++ ys            =  foldr (:) ys xs
204
205 instance  (Show a) => Show [a]  where
206     showsPrec p         = showList
207     showList            = showList__ (showsPrec 0)
208 \end{code}
209
210 \end{code}
211
212 A few list functions that appear here because they are used here.
213 The rest of the prelude list functions are in PrelList.
214
215 \begin{code}
216 foldr                   :: (a -> b -> b) -> b -> [a] -> b
217 foldr f z []            =  z
218 foldr f z (x:xs)        =  f x (foldr f z xs)
219
220 -- takeWhile, applied to a predicate p and a list xs, returns the longest
221 -- prefix (possibly empty) of xs of elements that satisfy p.  dropWhile p xs
222 -- returns the remaining suffix.  Span p xs is equivalent to 
223 -- (takeWhile p xs, dropWhile p xs), while break p uses the negation of p.
224
225 takeWhile               :: (a -> Bool) -> [a] -> [a]
226 takeWhile p []          =  []
227 takeWhile p (x:xs) 
228             | p x       =  x : takeWhile p xs
229             | otherwise =  []
230
231 dropWhile               :: (a -> Bool) -> [a] -> [a]
232 dropWhile p []          =  []
233 dropWhile p xs@(x:xs')
234             | p x       =  dropWhile p xs'
235             | otherwise =  xs
236
237 -- List index (subscript) operator, 0-origin
238 (!!)                    :: [a] -> Int -> a
239 (x:_)  !! 0             =  x
240 (_:xs) !! n | n > 0     =  xs !! (n-1)
241 (_:_)  !! _             =  error "PreludeList.!!: negative index"
242 []     !! _             =  error "PreludeList.!!: index too large"
243 \end{code}
244
245
246 %*********************************************************
247 %*                                                      *
248 \subsection{Type @Void@}
249 %*                                                      *
250 %*********************************************************
251
252 The type @Void@ is built in, but it needs a @Show@ instance.
253
254 \begin{code}
255 instance  Show Void  where
256     showsPrec p f  =  showString "<<void>>"
257     showList       = showList__ (showsPrec 0)
258 \end{code}
259
260
261 %*********************************************************
262 %*                                                      *
263 \subsection{Type @Bool@}
264 %*                                                      *
265 %*********************************************************
266
267 \begin{code}
268 data  Bool  =  False | True     deriving (Eq, Ord, Enum, Bounded, Show {- Read -})
269
270 -- Boolean functions
271
272 (&&), (||)              :: Bool -> Bool -> Bool
273 True  && x              =  x
274 False && _              =  False
275 True  || _              =  True
276 False || x              =  x
277
278 not                     :: Bool -> Bool
279 not True                =  False
280 not False               =  True
281
282 otherwise               :: Bool
283 otherwise               =  True
284 \end{code}
285
286
287 %*********************************************************
288 %*                                                      *
289 \subsection{Type @Maybe@}
290 %*                                                      *
291 %*********************************************************
292
293 \begin{code}
294 data  Maybe a  =  Nothing | Just a      deriving (Eq, Ord, Show {- Read -})
295
296 instance  Functor Maybe  where
297     map f Nothing       = Nothing
298     map f (Just a)      = Just (f a)
299
300 instance  Monad Maybe  where
301     (Just x) >>= k      = k x
302     Nothing  >>= k      = Nothing
303     return              = Just
304
305 instance  MonadZero Maybe  where
306     zero                = Nothing
307
308 instance  MonadPlus Maybe  where
309     Nothing ++ ys       = ys
310     xs      ++ ys       = xs
311 \end{code}
312
313
314 %*********************************************************
315 %*                                                      *
316 \subsection{The @()@ type}
317 %*                                                      *
318 %*********************************************************
319
320 The Unit type is here because virtually any program needs it (whereas
321 some programs may get away without consulting PrelTup).  Furthermore,
322 the renamer currently *always* asks for () to be in scope, so that
323 ccalls can use () as their default type; so when compiling PrelBase we
324 need ().  (We could arrange suck in () only if -fglasgow-exts, but putting
325 it here seems more direct.
326
327 \begin{code}
328 data  ()  =  ()  --easier to do explicitly: deriving (Eq, Ord, Enum, Show, Bounded)
329                  -- (avoids weird-named functions, e.g., con2tag_()#
330
331 instance Eq () where
332     () == () = True
333     () /= () = False
334
335 instance Ord () where
336     () <= () = True
337     () <  () = False
338     () >= () = True
339     () >  () = False
340     max () () = ()
341     min () () = ()
342     compare () () = EQ
343
344 instance Enum () where
345     toEnum 0    = ()
346     toEnum _    = error "Prelude.Enum.().toEnum: argument not 0"
347     fromEnum () = 0
348     enumFrom ()         = [()]
349     enumFromThen () ()  = [()]
350     enumFromTo () ()    = [()]
351     enumFromThenTo () () () = [()]
352
353 instance Bounded () where
354     minBound = ()
355     maxBound = ()
356
357 instance  Show ()  where
358     showsPrec p () = showString "()"
359 \end{code}
360
361 %*********************************************************
362 %*                                                      *
363 \subsection{Type @Either@}
364 %*                                                      *
365 %*********************************************************
366
367 \begin{code}
368 data  Either a b  =  Left a | Right b   deriving (Eq, Ord, Show {- Read -} )
369
370 either                  :: (a -> c) -> (b -> c) -> Either a b -> c
371 either f g (Left x)     =  f x
372 either f g (Right y)    =  g y
373 \end{code}
374
375
376 %*********************************************************
377 %*                                                      *
378 \subsection{Type @Ordering@}
379 %*                                                      *
380 %*********************************************************
381
382 \begin{code}
383 data Ordering = LT | EQ | GT    deriving (Eq, Ord, Enum, Bounded, Show {- Read -})
384 \end{code}
385
386
387 %*********************************************************
388 %*                                                      *
389 \subsection{Type @Char@ and @String@}
390 %*                                                      *
391 %*********************************************************
392
393 \begin{code}
394 type  String = [Char]
395
396 data Char = C# Char#    deriving (Eq, Ord)
397
398 instance  Enum Char  where
399     toEnum   (I# i) | i >=# 0# && i <=# 255# =  C# (chr# i)
400                     | otherwise = error "Prelude.Enum.Char.toEnum:out of range"
401     fromEnum (C# c)              =  I# (ord# c)
402
403     enumFrom (C# c)                        =  eftt (ord# c)  1#                   255#
404     enumFromThen (C# c1) (C# c2)           =  eftt (ord# c1) (ord# c2 -# ord# c1) 255#
405     enumFromThenTo (C# c1) (C# c2) (C# c3) =  eftt (ord# c1) (ord# c2 -# ord# c1) (ord# c3)
406
407 eftt :: Int# -> Int# -> Int# -> [Char]
408 eftt now step limit 
409   = go now
410   where
411     go now | now ># limit = []
412            | otherwise    = C# (chr# now) : go (now +# step)
413
414 instance  Bounded Char  where
415     minBound            =  '\0'
416     maxBound            =  '\255'
417
418 instance  Show Char  where
419     showsPrec p '\'' = showString "'\\''"
420     showsPrec p c    = showChar '\'' . showLitChar c . showChar '\''
421
422     showList cs = showChar '"' . showl cs
423                  where showl ""       = showChar '"'
424                        showl ('"':cs) = showString "\\\"" . showl cs
425                        showl (c:cs)   = showLitChar c . showl cs
426 \end{code}
427
428
429 \begin{code}
430 isAscii, isControl, isPrint, isSpace, isUpper,
431  isLower, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphanum :: Char -> Bool
432 isAscii c               =  fromEnum c < 128
433 isControl c             =  c < ' ' || c >= '\DEL' && c <= '\x9f'
434 isPrint c               =  not (isControl c)
435
436 -- isSpace includes non-breaking space
437 -- Done with explicit equalities both for efficiency, and to avoid a tiresome
438 -- recursion with PrelList elem
439 isSpace c               =  c == ' '     ||
440                            c == '\t'    ||
441                            c == '\n'    ||
442                            c == '\r'    ||
443                            c == '\f'    ||
444                            c == '\v'    ||
445                            c == '\xa0'
446
447 -- The upper case ISO characters have the multiplication sign dumped
448 -- randomly in the middle of the range.  Go figure.
449 isUpper c               =  c >= 'A' && c <= 'Z' || 
450                            c >= '\xC0' && c <= '\xD6' ||
451                            c >= '\xD8' && c <= '\xDE'
452 -- The lower case ISO characters have the division sign dumped
453 -- randomly in the middle of the range.  Go figure.
454 isLower c               =  c >= 'a' && c <= 'z' ||
455                            c >= '\xDF' && c <= '\xF6' ||
456                            c >= '\xF8' && c <= '\xFF'
457 isAlpha c               =  isUpper c || isLower c
458 isDigit c               =  c >= '0' && c <= '9'
459 isOctDigit c            =  c >= '0' && c <= '7'
460 isHexDigit c            =  isDigit c || c >= 'A' && c <= 'F' ||
461                                         c >= 'a' && c <= 'f'
462 isAlphanum c            =  isAlpha c || isDigit c
463
464 -- These almost work for ISO-Latin-1 (except for =DF <-> =FF)
465
466 toUpper, toLower        :: Char -> Char
467 toUpper c | isLower c   =  toEnum (fromEnum c - fromEnum 'a'
468                                               + fromEnum 'A')
469           | otherwise   =  c
470
471 toLower c | isUpper c   =  toEnum (fromEnum c - fromEnum 'A' 
472                                               + fromEnum 'a')
473           | otherwise   =  c
474
475 asciiTab = -- Using an array drags in the array module.  listArray ('\NUL', ' ')
476            ["NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
477             "BS",  "HT",  "LF",  "VT",  "FF",  "CR",  "SO",  "SI", 
478             "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
479             "CAN", "EM",  "SUB", "ESC", "FS",  "GS",  "RS",  "US", 
480             "SP"] 
481 \end{code}
482
483 %*********************************************************
484 %*                                                      *
485 \subsection{Type @Int@}
486 %*                                                      *
487 %*********************************************************
488
489 \begin{code}
490 data Int        = I# Int#                       deriving (Eq,Ord)
491
492 instance  Enum Int  where
493     toEnum   x = x
494     fromEnum x = x
495 #ifndef USE_FOLDR_BUILD
496     enumFrom x           =  x : enumFrom (x `plusInt` 1)
497     enumFromTo n m       =  takeWhile (<= m) (enumFrom n)
498 #else
499     {-# INLINE enumFrom #-}
500     {-# INLINE enumFromTo #-}
501     enumFrom x           = build (\ c _ -> 
502         let g x = x `c` g (x `plusInt` 1) in g x)
503     enumFromTo x y       = build (\ c n ->
504         let g x = if x <= y then x `c` g (x `plusInt` 1) else n in g x)
505 #endif
506     enumFromThen m n     =  en' m (n `minusInt` m)
507                             where en' m n = m : en' (m `plusInt` n) n
508     enumFromThenTo n m p =  takeWhile (if m >= n then (<= p) else (>= p))
509                                       (enumFromThen n m)
510
511 instance  Bounded Int where
512     minBound =  negate 2147483647   -- **********************
513     maxBound =  2147483647          -- **********************
514
515 instance  Num Int  where
516     (+)    x y =  plusInt x y
517     (-)    x y =  minusInt x y
518     negate x   =  negateInt x
519     (*)    x y =  timesInt x y
520     abs    n   = if n `geInt` 0 then n else (negateInt n)
521
522     signum n | n `ltInt` 0 = negateInt 1
523              | n `eqInt` 0 = 0
524              | otherwise   = 1
525
526     fromInteger (J# a# s# d#)
527       = case (integer2Int# a# s# d#) of { i# -> I# i# }
528
529     fromInt n           = n
530
531 instance  Show Int  where
532     showsPrec p n = showSignedInt p n
533     showList      = showList__ (showsPrec 0) 
534 \end{code}
535
536
537 %*********************************************************
538 %*                                                      *
539 \subsection{Type @Integer@, @Float@, @Double@}
540 %*                                                      *
541 %*********************************************************
542
543 Just the type declarations.  If we don't actually use any @Integers@ we'd
544 rather not link the @Integer@ module at all; and the default-decl stuff
545 in the renamer tends to slurp in @Double@ regardless.
546
547 \begin{code}
548 data Float      = F# Float#                     deriving (Eq, Ord)
549 data Double     = D# Double#                    deriving (Eq, Ord)
550 data Integer    = J# Int# Int# ByteArray#
551 \end{code}
552
553
554 %*********************************************************
555 %*                                                      *
556 \subsection{The function type}
557 %*                                                      *
558 %*********************************************************
559
560 \begin{code}
561 instance  Show (a -> b)  where
562     showsPrec p f  =  showString "<<function>>"
563     showList       = showList__ (showsPrec 0)
564
565 -- identity function
566 id                      :: a -> a
567 id x                    =  x
568
569 -- constant function
570 const                   :: a -> b -> a
571 const x _               =  x
572
573 -- function composition
574 {-# INLINE (.) #-}
575 {-# GENERATE_SPECS (.) a b c #-}
576 (.)                     :: (b -> c) -> (a -> b) -> a -> c
577 f . g                   =  \ x -> f (g x)
578
579 -- flip f  takes its (first) two arguments in the reverse order of f.
580 flip                    :: (a -> b -> c) -> b -> a -> c
581 flip f x y              =  f y x
582
583 -- right-associating infix application operator (useful in continuation-
584 -- passing style)
585 ($)                     :: (a -> b) -> a -> b
586 f $ x                   =  f x
587
588 -- until p f  yields the result of applying f until p holds.
589 until                   :: (a -> Bool) -> (a -> a) -> a -> a
590 until p f x | p x       =  x
591             | otherwise =  until p f (f x)
592
593 -- asTypeOf is a type-restricted version of const.  It is usually used
594 -- as an infix operator, and its typing forces its first argument
595 -- (which is usually overloaded) to have the same type as the second.
596 asTypeOf                :: a -> a -> a
597 asTypeOf                =  const
598 \end{code}
599
600
601 %*********************************************************
602 %*                                                      *
603 \subsection{Miscellaneous}
604 %*                                                      *
605 %*********************************************************
606
607
608 \begin{code}
609 data Addr = A# Addr#    deriving (Eq, Ord) -- Glasgow extension
610 data Word = W# Word#    deriving (Eq, Ord) -- Glasgow extension
611
612 data Lift a = Lift a
613 {-# GENERATE_SPECS data a :: Lift a #-}
614 \end{code}
615
616
617
618
619 %*********************************************************
620 %*                                                      *
621 \subsection{Support code for @Show@}
622 %*                                                      *
623 %*********************************************************
624
625 \begin{code}
626 shows           :: (Show a) => a -> ShowS
627 shows           =  showsPrec 0
628
629 show            :: (Show a) => a -> String
630 show x          =  shows x ""
631
632 showChar        :: Char -> ShowS
633 showChar        =  (:)
634
635 showString      :: String -> ShowS
636 showString      =  (++)
637
638 showParen       :: Bool -> ShowS -> ShowS
639 showParen b p   =  if b then showChar '(' . p . showChar ')' else p
640
641 {-# GENERATE_SPECS showList__ a #-}
642 showList__ :: (a -> ShowS) ->  [a] -> ShowS
643
644 showList__ showx []     = showString "[]"
645 showList__ showx (x:xs) = showChar '[' . showx x . showl xs
646   where
647     showl []     = showChar ']'
648     showl (x:xs) = showString ", " . showx x . showl xs
649
650 showSpace :: ShowS
651 showSpace = {-showChar ' '-} \ xs -> ' ' : xs
652 \end{code}
653
654 Code specific for characters
655
656 \begin{code}
657 showLitChar                :: Char -> ShowS
658 showLitChar c | c > '\DEL' =  showChar '\\' . protectEsc isDigit (shows (ord c))
659 showLitChar '\DEL'         =  showString "\\DEL"
660 showLitChar '\\'           =  showString "\\\\"
661 showLitChar c | c >= ' '   =  showChar c
662 showLitChar '\a'           =  showString "\\a"
663 showLitChar '\b'           =  showString "\\b"
664 showLitChar '\f'           =  showString "\\f"
665 showLitChar '\n'           =  showString "\\n"
666 showLitChar '\r'           =  showString "\\r"
667 showLitChar '\t'           =  showString "\\t"
668 showLitChar '\v'           =  showString "\\v"
669 showLitChar '\SO'          =  protectEsc (== 'H') (showString "\\SO")
670 showLitChar c              =  showString ('\\' : asciiTab!!ord c)
671
672 protectEsc p f             = f . cont
673                              where cont s@(c:_) | p c = "\\&" ++ s
674                                    cont s             = s
675 \end{code}
676
677 Code specific for Ints.
678
679 \begin{code}
680 showSignedInt :: Int -> Int -> ShowS
681 showSignedInt p (I# n) r
682   = -- from HBC version; support code follows
683     if n <# 0# && p > 6 then '(':itos n++(')':r) else itos n ++ r
684
685 itos :: Int# -> String
686 itos n =
687     if n <# 0# then
688         if negateInt# n <# 0# then
689             -- n is minInt, a difficult number
690             itos (n `quotInt#` 10#) ++ itos' (negateInt# (n `remInt#` 10#)) []
691         else
692             '-':itos' (negateInt# n) []
693     else 
694         itos' n []
695   where
696     itos' :: Int# -> String -> String
697     itos' n cs = 
698         if n <# 10# then
699             C# (chr# (n +# ord# '0'#)) : cs
700         else 
701             itos' (n `quotInt#` 10#) (C# (chr# (n `remInt#` 10# +# ord# '0'#)) : cs)
702 \end{code}
703
704 %*********************************************************
705 %*                                                      *
706 \subsection{Numeric primops}
707 %*                                                      *
708 %*********************************************************
709
710 Definitions of the boxed PrimOps; these will be
711 used in the case of partial applications, etc.
712
713 \begin{code}
714 plusInt (I# x) (I# y) = I# (x +# y)
715 minusInt(I# x) (I# y) = I# (x -# y)
716 timesInt(I# x) (I# y) = I# (x *# y)
717 quotInt (I# x) (I# y) = I# (quotInt# x y)
718 remInt  (I# x) (I# y) = I# (remInt# x y)
719 negateInt (I# x)      = I# (negateInt# x)
720 gtInt   (I# x) (I# y) = x ># y
721 geInt   (I# x) (I# y) = x >=# y
722 eqInt   (I# x) (I# y) = x ==# y
723 neInt   (I# x) (I# y) = x /=# y
724 ltInt   (I# x) (I# y) = x <# y
725 leInt   (I# x) (I# y) = x <=# y
726 \end{code}