2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[PrelBase]{Module @PrelBase@}
8 {-# OPTIONS -fno-implicit-prelude #-}
12 import {-# SOURCE #-} IOBase ( error )
19 infix 4 ==, /=, <, <=, >=, >
26 %*********************************************************
28 \subsection{Standard classes @Eq@, @Ord@, @Bounded@, @Eval@}
30 %*********************************************************
34 (==), (/=) :: a -> a -> Bool
38 class (Eq a) => Ord a where
39 compare :: a -> a -> Ordering
40 (<), (<=), (>=), (>):: a -> a -> Bool
41 max, min :: a -> a -> a
43 -- An instance of Ord should define either compare or <=
44 -- Using compare can be more efficient for complex types.
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 }
58 minBound, maxBound :: a
63 %*********************************************************
65 \subsection{Monadic classes @Functor@, @Monad@, @MonadZero@, @MonadPlus@}
67 %*********************************************************
71 map :: (a -> b) -> f a -> f b
74 (>>=) :: m a -> (a -> m b) -> m b
75 (>>) :: m a -> m b -> m b
78 m >> k = m >>= \_ -> k
80 class (Monad m) => MonadZero m where
83 class (MonadZero m) => MonadPlus m where
84 (++) :: m a -> m a -> m a
88 %*********************************************************
90 \subsection{Classes @Num@ and @Enum@}
92 %*********************************************************
95 class (Ord a) => Enum a where
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]
103 enumFromTo n m = takeWhile (<= m) (enumFrom n)
104 enumFromThenTo n n' m
105 = takeWhile (if n' >= n then (<= m) else (>= m))
108 class (Eq a, Show a, Eval a) => Num a where
109 (+), (-), (*) :: a -> a -> a
111 abs, signum :: a -> a
112 fromInteger :: Integer -> a
113 fromInt :: Int -> a -- partain: Glasgow extension
116 fromInt (I# i#) = fromInteger (int2Integer# i#)
117 -- Go via the standard class-op if the
118 -- non-standard one ain't provided
122 succ, pred :: Enum a => a -> a
123 succ = toEnum . (+1) . fromEnum
124 pred = toEnum . (subtract 1) . fromEnum
126 chr = (toEnum :: Int -> Char)
127 ord = (fromEnum :: Char -> Int)
130 ord_0 = fromInt (ord '0')
132 {-# GENERATE_SPECS subtract a{Int#,Double#,Int,Double,Complex(Double#),Complex(Double)} #-}
133 subtract :: (Num a) => a -> a -> a
138 %*********************************************************
140 \subsection{The @Show@ class}
142 %*********************************************************
145 type ShowS = String -> String
148 showsPrec :: Int -> a -> ShowS
149 showList :: [a] -> ShowS
151 showList [] = showString "[]"
153 = showChar '[' . shows x . showl xs
154 where showl [] = showChar ']'
155 showl (x:xs) = showString ", " . shows x . showl xs
158 %*********************************************************
160 \subsection{The list type}
162 %*********************************************************
165 data [] a = [] | a : [a] -- do explicitly: deriving (Eq, Ord)
166 -- to avoid weird names like con2tag_[]#
168 instance (Eq a) => Eq [a] where
170 (x:xs) == (y:ys) = x == y && xs == ys
173 xs /= ys = if (xs == ys) then False else True
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 }
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 }
185 compare (x:xs) [] = GT
186 compare [] (y:ys) = LT
187 compare (x:xs) (y:ys) = case compare x y of
192 instance Functor [] where
194 map f (x:xs) = f x : map f xs
196 instance Monad [] where
197 m >>= k = foldr ((++) . k) [] m
200 instance MonadZero [] where
203 instance MonadPlus [] where
204 xs ++ ys = foldr (:) ys xs
206 instance (Show a) => Show [a] where
207 showsPrec p = showList
208 showList = showList__ (showsPrec 0)
213 A few list functions that appear here because they are used here.
214 The rest of the prelude list functions are in PrelList.
217 foldr :: (a -> b -> b) -> b -> [a] -> b
219 foldr f z (x:xs) = f x (foldr f z xs)
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.
226 takeWhile :: (a -> Bool) -> [a] -> [a]
229 | p x = x : takeWhile p xs
232 dropWhile :: (a -> Bool) -> [a] -> [a]
234 dropWhile p xs@(x:xs')
235 | p x = dropWhile p xs'
238 -- List index (subscript) operator, 0-origin
239 (!!) :: [a] -> Int -> a
241 (_:xs) !! n | n > 0 = xs !! (n-1)
242 (_:_) !! _ = error "PreludeList.!!: negative index"
243 [] !! _ = error "PreludeList.!!: index too large"
247 %*********************************************************
249 \subsection{Type @Void@}
251 %*********************************************************
253 The type @Void@ is built in, but it needs a @Show@ instance.
256 instance Show Void where
257 showsPrec p f = showString "<<void>>"
258 showList = showList__ (showsPrec 0)
262 %*********************************************************
264 \subsection{Type @Bool@}
266 %*********************************************************
269 data Bool = False | True deriving (Eq, Ord, Enum, Bounded, Show {- Read -})
273 (&&), (||) :: Bool -> Bool -> Bool
288 %*********************************************************
290 \subsection{Type @Maybe@}
292 %*********************************************************
295 data Maybe a = Nothing | Just a deriving (Eq, Ord, Show {- Read -})
297 instance Functor Maybe where
298 map f Nothing = Nothing
299 map f (Just a) = Just (f a)
301 instance Monad Maybe where
303 Nothing >>= k = Nothing
306 instance MonadZero Maybe where
309 instance MonadPlus Maybe where
315 %*********************************************************
317 \subsection{The @()@ type}
319 %*********************************************************
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.
329 data () = () --easier to do explicitly: deriving (Eq, Ord, Enum, Show, Bounded)
330 -- (avoids weird-named functions, e.g., con2tag_()#
336 instance Ord () where
345 instance Enum () where
347 toEnum _ = error "Prelude.Enum.().toEnum: argument not 0"
350 enumFromThen () () = [()]
351 enumFromTo () () = [()]
352 enumFromThenTo () () () = [()]
354 instance Bounded () where
358 instance Show () where
359 showsPrec p () = showString "()"
362 %*********************************************************
364 \subsection{Type @Either@}
366 %*********************************************************
369 data Either a b = Left a | Right b deriving (Eq, Ord, Show {- Read -} )
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
377 %*********************************************************
379 \subsection{Type @Ordering@}
381 %*********************************************************
384 data Ordering = LT | EQ | GT deriving (Eq, Ord, Enum, Bounded, Show {- Read -})
388 %*********************************************************
390 \subsection{Type @Char@ and @String@}
392 %*********************************************************
397 data Char = C# Char# deriving (Eq, Ord)
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)
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)
408 eftt :: Int# -> Int# -> Int# -> [Char]
412 go now | now ># limit = []
413 | otherwise = C# (chr# now) : go (now +# step)
415 instance Bounded Char where
419 instance Show Char where
420 showsPrec p '\'' = showString "'\\''"
421 showsPrec p c = showChar '\'' . showLitChar c . showChar '\''
423 showList cs = showChar '"' . showl cs
424 where showl "" = showChar '"'
425 showl ('"':cs) = showString "\\\"" . showl cs
426 showl (c:cs) = showLitChar c . showl cs
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)
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 == ' ' ||
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' ||
463 isAlphanum c = isAlpha c || isDigit c
465 -- These almost work for ISO-Latin-1 (except for =DF <-> =FF)
467 toUpper, toLower :: Char -> Char
468 toUpper c | isLower c = toEnum (fromEnum c - fromEnum 'a'
472 toLower c | isUpper c = toEnum (fromEnum c - fromEnum 'A'
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",
484 %*********************************************************
486 \subsection{Type @Int@}
488 %*********************************************************
493 instance Eq Int where
494 (I# x) == (I# y) = x ==# y
496 instance Ord Int where
497 (I# x) `compare` (I# y) | x <# y = LT
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
508 instance Enum Int where
511 #ifndef USE_FOLDR_BUILD
512 enumFrom x = x : enumFrom (x `plusInt` 1)
513 enumFromTo n m = takeWhile (<= m) (enumFrom n)
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)
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))
527 instance Bounded Int where
528 minBound = negate 2147483647 -- **********************
529 maxBound = 2147483647 -- **********************
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)
538 signum n | n `ltInt` 0 = negateInt 1
542 fromInteger (J# a# s# d#)
543 = case (integer2Int# a# s# d#) of { i# -> I# i# }
547 instance Show Int where
548 showsPrec p n = showSignedInt p n
549 showList = showList__ (showsPrec 0)
553 %*********************************************************
555 \subsection{Type @Integer@, @Float@, @Double@}
557 %*********************************************************
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.
564 data Float = F# Float#
565 data Double = D# Double#
566 data Integer = J# Int# Int# ByteArray#
570 %*********************************************************
572 \subsection{The function type}
574 %*********************************************************
577 instance Show (a -> b) where
578 showsPrec p f = showString "<<function>>"
579 showList = showList__ (showsPrec 0)
589 -- function composition
591 {-# GENERATE_SPECS (.) a b c #-}
592 (.) :: (b -> c) -> (a -> b) -> a -> c
593 f . g = \ x -> f (g x)
595 -- flip f takes its (first) two arguments in the reverse order of f.
596 flip :: (a -> b -> c) -> b -> a -> c
599 -- right-associating infix application operator (useful in continuation-
601 ($) :: (a -> b) -> a -> b
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)
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
617 %*********************************************************
619 \subsection{Miscellaneous}
621 %*********************************************************
625 data Addr = A# Addr# deriving (Eq, Ord) -- Glasgow extension
626 data Word = W# Word# deriving (Eq, Ord) -- Glasgow extension
629 {-# GENERATE_SPECS data a :: Lift a #-}
635 %*********************************************************
637 \subsection{Support code for @Show@}
639 %*********************************************************
642 shows :: (Show a) => a -> ShowS
645 show :: (Show a) => a -> String
648 showChar :: Char -> ShowS
651 showString :: String -> ShowS
654 showParen :: Bool -> ShowS -> ShowS
655 showParen b p = if b then showChar '(' . p . showChar ')' else p
657 {-# GENERATE_SPECS showList__ a #-}
658 showList__ :: (a -> ShowS) -> [a] -> ShowS
660 showList__ showx [] = showString "[]"
661 showList__ showx (x:xs) = showChar '[' . showx x . showl xs
663 showl [] = showChar ']'
664 showl (x:xs) = showString ", " . showx x . showl xs
667 showSpace = {-showChar ' '-} \ xs -> ' ' : xs
670 Code specific for characters
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)
688 protectEsc p f = f . cont
689 where cont s@(c:_) | p c = "\\&" ++ s
693 Code specific for Ints.
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
701 itos :: Int# -> String
704 if negateInt# n <# 0# then
705 -- n is minInt, a difficult number
706 itos (n `quotInt#` 10#) ++ itos' (negateInt# (n `remInt#` 10#)) []
708 '-':itos' (negateInt# n) []
712 itos' :: Int# -> String -> String
715 C# (chr# (n +# ord# '0'#)) : cs
717 itos' (n `quotInt#` 10#) (C# (chr# (n `remInt#` 10# +# ord# '0'#)) : cs)
720 %*********************************************************
722 \subsection{Numeric primops}
724 %*********************************************************
726 Definitions of the boxed PrimOps; these will be
727 used in the case of partial applications, etc.
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