2 % (c) The GRAP/AQUA Project, Glasgow University, 1992-1996
4 \section{Module @PrelShow@}
8 {-# OPTIONS -fno-implicit-prelude #-}
14 -- Instances for Show: (), [], Bool, Ordering, Int, Char
17 shows, showChar, showString, showParen, showList__, showSpace,
18 showLitChar, protectEsc,
19 intToDigit, showSignedInt,
21 -- Character operations
22 isAscii, isLatin1, isControl, isPrint, isSpace, isUpper,
23 isLower, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum,
28 lines, unlines, words, unwords
32 import {-# SOURCE #-} PrelErr ( error )
35 import PrelList ( (!!), break, dropWhile
36 #ifdef USE_REPORT_PRELUDE
44 %*********************************************************
46 \subsection{The @Show@ class}
48 %*********************************************************
51 type ShowS = String -> String
54 showsPrec :: Int -> a -> ShowS
56 showList :: [a] -> ShowS
58 showsPrec _ x s = show x ++ s
60 showList ls = showList__ shows ls
62 showList__ :: (a -> ShowS) -> [a] -> ShowS
63 showList__ _ [] s = "[]" ++ s
64 showList__ showx (x:xs) s = '[' : showx x (showl xs)
67 showl (y:ys) = ',' : showx y (showl ys)
70 %*********************************************************
72 \subsection{Simple Instances}
74 %*********************************************************
78 instance Show () where
79 showsPrec _ () = showString "()"
81 instance Show a => Show [a] where
82 showsPrec _ = showList
84 instance Show Bool where
85 showsPrec _ True = showString "True"
86 showsPrec _ False = showString "False"
88 instance Show Ordering where
89 showsPrec _ LT = showString "LT"
90 showsPrec _ EQ = showString "EQ"
91 showsPrec _ GT = showString "GT"
93 instance Show Char where
94 showsPrec _ '\'' = showString "'\\''"
95 showsPrec _ c = showChar '\'' . showLitChar c . showChar '\''
97 showList cs = showChar '"' . showl cs
98 where showl "" = showChar '"'
99 showl ('"':xs) = showString "\\\"" . showl xs
100 showl (x:xs) = showLitChar x . showl xs
102 instance Show Int where
103 showsPrec p n = showSignedInt p n
105 instance Show a => Show (Maybe a) where
106 showsPrec _p Nothing = showString "Nothing"
107 showsPrec p@(I# p#) (Just x)
108 = showParen (p# >=# 10#) $
112 instance (Show a, Show b) => Show (Either a b) where
113 showsPrec p@(I# p#) e =
114 showParen (p# >=# 10#) $
116 Left a -> showString "Left " . showsPrec (I# 10#) a
117 Right b -> showString "Right " . showsPrec (I# 10#) b
122 %*********************************************************
124 \subsection{Show instances for the first few tuples
126 %*********************************************************
129 instance (Show a, Show b) => Show (a,b) where
130 showsPrec _ (x,y) = showChar '(' . shows x . showChar ',' .
131 shows y . showChar ')'
133 instance (Show a, Show b, Show c) => Show (a, b, c) where
134 showsPrec _ (x,y,z) = showChar '(' . shows x . showChar ',' .
135 shows y . showChar ',' .
136 shows z . showChar ')'
138 instance (Show a, Show b, Show c, Show d) => Show (a, b, c, d) where
139 showsPrec _ (w,x,y,z) = showChar '(' . shows w . showChar ',' .
140 shows x . showChar ',' .
141 shows y . showChar ',' .
142 shows z . showChar ')'
144 instance (Show a, Show b, Show c, Show d, Show e) => Show (a, b, c, d, e) where
145 showsPrec _ (v,w,x,y,z) = showChar '(' . shows v . showChar ',' .
146 shows w . showChar ',' .
147 shows x . showChar ',' .
148 shows y . showChar ',' .
149 shows z . showChar ')'
153 %*********************************************************
155 \subsection{Support code for @Show@}
157 %*********************************************************
160 shows :: (Show a) => a -> ShowS
161 shows = showsPrec zeroInt
163 showChar :: Char -> ShowS
166 showString :: String -> ShowS
169 showParen :: Bool -> ShowS -> ShowS
170 showParen b p = if b then showChar '(' . p . showChar ')' else p
173 showSpace = {-showChar ' '-} \ xs -> ' ' : xs
176 Code specific for characters
179 showLitChar :: Char -> ShowS
180 showLitChar c | c > '\DEL' = showChar '\\' . protectEsc isDigit (shows (ord c))
181 showLitChar '\DEL' = showString "\\DEL"
182 showLitChar '\\' = showString "\\\\"
183 showLitChar c | c >= ' ' = showChar c
184 showLitChar '\a' = showString "\\a"
185 showLitChar '\b' = showString "\\b"
186 showLitChar '\f' = showString "\\f"
187 showLitChar '\n' = showString "\\n"
188 showLitChar '\r' = showString "\\r"
189 showLitChar '\t' = showString "\\t"
190 showLitChar '\v' = showString "\\v"
191 showLitChar '\SO' = protectEsc (== 'H') (showString "\\SO")
192 showLitChar c = showString ('\\' : asciiTab!!ord c)
194 protectEsc :: (Char -> Bool) -> ShowS -> ShowS
195 protectEsc p f = f . cont
196 where cont s@(c:_) | p c = "\\&" ++ s
199 intToDigit :: Int -> Char
201 | i >=# 0# && i <=# 9# = unsafeChr (ord '0' `plusInt` I# i)
202 | i >=# 10# && i <=# 15# = unsafeChr (ord 'a' `plusInt` I# i `minusInt` I# 10#)
203 | otherwise = error ("Char.intToDigit: not a digit " ++ show (I# i))
207 Code specific for Ints.
210 showSignedInt :: Int -> Int -> ShowS
211 showSignedInt (I# p) (I# n) r
212 | n <# 0# && p ># 6# = '(':itos n (')':r)
213 | otherwise = itos n r
215 itos :: Int# -> String -> String
217 | n >=# 0# = itos' n r
218 | negateInt# n <# 0# = -- n is minInt, a difficult number
219 itos (n `quotInt#` 10#) (itos' (negateInt# (n `remInt#` 10#)) r)
220 | otherwise = '-':itos' (negateInt# n) r
222 itos' :: Int# -> String -> String
225 | x <# 10# = C# (chr# (x +# ord# '0'#)) : cs
226 | otherwise = itos' (x `quotInt#` 10#)
227 (C# (chr# (x `remInt#` 10# +# ord# '0'#)) : cs)
232 %*********************************************************
234 \subsection{Character stuff}
236 %*********************************************************
239 isAscii, isLatin1, isControl, isPrint, isSpace, isUpper,
240 isLower, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum :: Char -> Bool
241 isAscii c = c < '\x80'
242 isLatin1 c = c <= '\xff'
243 isControl c = c < ' ' || c >= '\DEL' && c <= '\x9f'
244 isPrint c = not (isControl c)
246 -- isSpace includes non-breaking space
247 -- Done with explicit equalities both for efficiency, and to avoid a tiresome
248 -- recursion with PrelList elem
249 isSpace c = c == ' ' ||
257 -- The upper case ISO characters have the multiplication sign dumped
258 -- randomly in the middle of the range. Go figure.
259 isUpper c = c >= 'A' && c <= 'Z' ||
260 c >= '\xC0' && c <= '\xD6' ||
261 c >= '\xD8' && c <= '\xDE'
262 -- The lower case ISO characters have the division sign dumped
263 -- randomly in the middle of the range. Go figure.
264 isLower c = c >= 'a' && c <= 'z' ||
265 c >= '\xDF' && c <= '\xF6' ||
266 c >= '\xF8' && c <= '\xFF'
267 isAsciiLower c = c >= 'a' && c <= 'z'
268 isAsciiUpper c = c >= 'A' && c <= 'Z'
270 isAlpha c = isLower c || isUpper c
271 isDigit c = c >= '0' && c <= '9'
272 isOctDigit c = c >= '0' && c <= '7'
273 isHexDigit c = isDigit c || c >= 'A' && c <= 'F' ||
275 isAlphaNum c = isAlpha c || isDigit c
277 -- Case-changing operations
279 toUpper, toLower :: Char -> Char
281 | isAsciiLower c = C# (chr# (ord# c# -# 32#))
283 -- fall-through to the slower stuff.
284 | isLower c && c /= '\xDF' && c /= '\xFF'
285 = unsafeChr (ord c `minusInt` ord 'a' `plusInt` ord 'A')
292 | isAsciiUpper c = C# (chr# (ord# c# +# 32#))
294 | isUpper c = unsafeChr (ord c `minusInt` ord 'A' `plusInt` ord 'a')
298 asciiTab = -- Using an array drags in the array module. listArray ('\NUL', ' ')
299 ["NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
300 "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
301 "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
302 "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US",
306 %*********************************************************
308 \subsection{Functions on strings}
310 %*********************************************************
312 lines breaks a string up into a list of strings at newline characters.
313 The resulting strings do not contain newlines. Similary, words
314 breaks a string up into a list of words, which were delimited by
315 white space. unlines and unwords are the inverse operations.
316 unlines joins lines with terminating newlines, and unwords joins
317 words with separating spaces.
320 lines :: String -> [String]
322 lines s = let (l, s') = break (== '\n') s
327 words :: String -> [String]
328 words s = case dropWhile {-partain:Char.-}isSpace s of
332 break {-partain:Char.-}isSpace s'
334 unlines :: [String] -> String
335 #ifdef USE_REPORT_PRELUDE
336 unlines = concatMap (++ "\n")
338 -- HBC version (stolen)
339 -- here's a more efficient version
341 unlines (l:ls) = l ++ '\n' : unlines ls
344 unwords :: [String] -> String
345 #ifdef USE_REPORT_PRELUDE
347 unwords ws = foldr1 (\w s -> w ++ ' ':s) ws
349 -- HBC version (stolen)
350 -- here's a more efficient version
353 unwords (w:ws) = w ++ ' ' : unwords ws