2 {-# OPTIONS -fno-implicit-prelude #-}
3 -----------------------------------------------------------------------------
6 -- Copyright : (c) The University of Glasgow, 1992-2002
7 -- License : see libraries/base/LICENSE
9 -- Maintainer : cvs-ghc@haskell.org
10 -- Stability : internal
11 -- Portability : non-portable (GHC Extensions)
13 -- The 'Show' class, and related operations.
15 -----------------------------------------------------------------------------
21 -- Instances for Show: (), [], Bool, Ordering, Int, Char
24 shows, showChar, showString, showParen, showList__, showSpace,
25 showLitChar, protectEsc,
26 intToDigit, showSignedInt,
29 -- Character operations
34 import {-# SOURCE #-} GHC.Err ( error )
39 import GHC.List ( (!!),
40 #ifdef USE_REPORT_PRELUDE
48 %*********************************************************
50 \subsection{The @Show@ class}
52 %*********************************************************
55 type ShowS = String -> String
58 showsPrec :: Int -> a -> ShowS
60 showList :: [a] -> ShowS
62 showsPrec _ x s = show x ++ s
64 showList ls s = showList__ shows ls s
66 showList__ :: (a -> ShowS) -> [a] -> ShowS
67 showList__ _ [] s = "[]" ++ s
68 showList__ showx (x:xs) s = '[' : showx x (showl xs)
71 showl (y:ys) = ',' : showx y (showl ys)
73 appPrec, appPrec1 :: Int
74 -- Use unboxed stuff because we don't have overloaded numerics yet
75 appPrec = I# 10# -- Precedence of application:
76 -- one more than the maximum operator precedence of 9
77 appPrec1 = I# 11# -- appPrec + 1
80 %*********************************************************
82 \subsection{Simple Instances}
84 %*********************************************************
88 instance Show () where
89 showsPrec _ () = showString "()"
91 instance Show a => Show [a] where
92 showsPrec _ = showList
94 instance Show Bool where
95 showsPrec _ True = showString "True"
96 showsPrec _ False = showString "False"
98 instance Show Ordering where
99 showsPrec _ LT = showString "LT"
100 showsPrec _ EQ = showString "EQ"
101 showsPrec _ GT = showString "GT"
103 instance Show Char where
104 showsPrec _ '\'' = showString "'\\''"
105 showsPrec _ c = showChar '\'' . showLitChar c . showChar '\''
107 showList cs = showChar '"' . showl cs
108 where showl "" s = showChar '"' s
109 showl ('"':xs) s = showString "\\\"" (showl xs s)
110 showl (x:xs) s = showLitChar x (showl xs s)
111 -- Making 's' an explicit parameter makes it clear to GHC
112 -- that showl has arity 2, which avoids it allocating an extra lambda
113 -- The sticking point is the recursive call to (showl xs), which
114 -- it can't figure out would be ok with arity 2.
116 instance Show Int where
117 showsPrec = showSignedInt
119 instance Show a => Show (Maybe a) where
120 showsPrec _p Nothing s = showString "Nothing" s
121 showsPrec p (Just x) s
122 = (showParen (p > appPrec) $
124 showsPrec appPrec1 x) s
126 instance (Show a, Show b) => Show (Either a b) where
128 (showParen (p > appPrec) $
130 Left a -> showString "Left " . showsPrec appPrec1 a
131 Right b -> showString "Right " . showsPrec appPrec1 b)
136 %*********************************************************
138 \subsection{Show instances for the first few tuples
140 %*********************************************************
143 -- The explicit 's' parameters are important
144 -- Otherwise GHC thinks that "shows x" might take a lot of work to compute
145 -- and generates defns like
146 -- showsPrec _ (x,y) = let sx = shows x; sy = shows y in
147 -- \s -> showChar '(' (sx (showChar ',' (sy (showChar ')' s))))
149 instance (Show a, Show b) => Show (a,b) where
150 showsPrec _ (x,y) s = (showChar '(' . shows x . showChar ',' .
151 shows y . showChar ')')
154 instance (Show a, Show b, Show c) => Show (a, b, c) where
155 showsPrec _ (x,y,z) s = (showChar '(' . shows x . showChar ',' .
156 shows y . showChar ',' .
157 shows z . showChar ')')
160 instance (Show a, Show b, Show c, Show d) => Show (a, b, c, d) where
161 showsPrec _ (w,x,y,z) s = (showChar '(' . shows w . showChar ',' .
162 shows x . showChar ',' .
163 shows y . showChar ',' .
164 shows z . showChar ')')
167 instance (Show a, Show b, Show c, Show d, Show e) => Show (a, b, c, d, e) where
168 showsPrec _ (v,w,x,y,z) s = (showChar '(' . shows v . showChar ',' .
169 shows w . showChar ',' .
170 shows x . showChar ',' .
171 shows y . showChar ',' .
172 shows z . showChar ')')
177 %*********************************************************
179 \subsection{Support code for @Show@}
181 %*********************************************************
184 shows :: (Show a) => a -> ShowS
185 shows = showsPrec zeroInt
187 showChar :: Char -> ShowS
190 showString :: String -> ShowS
193 showParen :: Bool -> ShowS -> ShowS
194 showParen b p = if b then showChar '(' . p . showChar ')' else p
197 showSpace = {-showChar ' '-} \ xs -> ' ' : xs
200 Code specific for characters
203 -- | Convert a character to a string using only printable characters,
204 -- using Haskell source-language escape conventions. For example:
206 -- > showLitChar '\n' s = "\\n" ++ s
208 showLitChar :: Char -> ShowS
209 showLitChar c s | c > '\DEL' = showChar '\\' (protectEsc isDec (shows (ord c)) s)
210 showLitChar '\DEL' s = showString "\\DEL" s
211 showLitChar '\\' s = showString "\\\\" s
212 showLitChar c s | c >= ' ' = showChar c s
213 showLitChar '\a' s = showString "\\a" s
214 showLitChar '\b' s = showString "\\b" s
215 showLitChar '\f' s = showString "\\f" s
216 showLitChar '\n' s = showString "\\n" s
217 showLitChar '\r' s = showString "\\r" s
218 showLitChar '\t' s = showString "\\t" s
219 showLitChar '\v' s = showString "\\v" s
220 showLitChar '\SO' s = protectEsc (== 'H') (showString "\\SO") s
221 showLitChar c s = showString ('\\' : asciiTab!!ord c) s
222 -- I've done manual eta-expansion here, becuase otherwise it's
223 -- impossible to stop (asciiTab!!ord) getting floated out as an MFE
225 isDec c = c >= '0' && c <= '9'
227 protectEsc :: (Char -> Bool) -> ShowS -> ShowS
228 protectEsc p f = f . cont
229 where cont s@(c:_) | p c = "\\&" ++ s
234 asciiTab = -- Using an array drags in the array module. listArray ('\NUL', ' ')
235 ["NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
236 "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
237 "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
238 "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US",
242 Code specific for Ints.
245 -- | Convert an 'Int' in the range @0@..@15@ to the corresponding single
246 -- digit 'Char'. This function fails on other inputs, and generates
247 -- lower-case hexadecimal digits.
248 intToDigit :: Int -> Char
250 | i >=# 0# && i <=# 9# = unsafeChr (ord '0' `plusInt` I# i)
251 | i >=# 10# && i <=# 15# = unsafeChr (ord 'a' `minusInt` ten `plusInt` I# i)
252 | otherwise = error ("Char.intToDigit: not a digit " ++ show (I# i))
256 showSignedInt :: Int -> Int -> ShowS
257 showSignedInt (I# p) (I# n) r
258 | n <# 0# && p ># 6# = '(' : itos n (')' : r)
259 | otherwise = itos n r
261 itos :: Int# -> String -> String
265 in if n'# <# 0# -- minInt?
266 then '-' : itos' (negateInt# (n'# `quotInt#` 10#))
267 (itos' (negateInt# (n'# `remInt#` 10#)) cs)
268 else '-' : itos' n'# cs
269 | otherwise = itos' n# cs
271 itos' :: Int# -> String -> String
273 | n# <# 10# = C# (chr# (ord# '0'# +# n#)) : cs
274 | otherwise = case chr# (ord# '0'# +# (n# `remInt#` 10#)) of { c# ->
275 itos' (n# `quotInt#` 10#) (C# c# : cs) }