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