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 showLitChar :: Char -> ShowS
204 showLitChar c s | c > '\DEL' = showChar '\\' (protectEsc isDec (shows (ord c)) s)
205 showLitChar '\DEL' s = showString "\\DEL" s
206 showLitChar '\\' s = showString "\\\\" s
207 showLitChar c s | c >= ' ' = showChar c s
208 showLitChar '\a' s = showString "\\a" s
209 showLitChar '\b' s = showString "\\b" s
210 showLitChar '\f' s = showString "\\f" s
211 showLitChar '\n' s = showString "\\n" s
212 showLitChar '\r' s = showString "\\r" s
213 showLitChar '\t' s = showString "\\t" s
214 showLitChar '\v' s = showString "\\v" s
215 showLitChar '\SO' s = protectEsc (== 'H') (showString "\\SO") s
216 showLitChar c s = showString ('\\' : asciiTab!!ord c) s
217 -- I've done manual eta-expansion here, becuase otherwise it's
218 -- impossible to stop (asciiTab!!ord) getting floated out as an MFE
220 isDec c = c >= '0' && c <= '9'
222 protectEsc :: (Char -> Bool) -> ShowS -> ShowS
223 protectEsc p f = f . cont
224 where cont s@(c:_) | p c = "\\&" ++ s
229 asciiTab = -- Using an array drags in the array module. listArray ('\NUL', ' ')
230 ["NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
231 "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
232 "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
233 "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US",
237 Code specific for Ints.
240 intToDigit :: Int -> Char
242 | i >=# 0# && i <=# 9# = unsafeChr (ord '0' `plusInt` I# i)
243 | i >=# 10# && i <=# 15# = unsafeChr (ord 'a' `minusInt` ten `plusInt` I# i)
244 | otherwise = error ("Char.intToDigit: not a digit " ++ show (I# i))
248 showSignedInt :: Int -> Int -> ShowS
249 showSignedInt (I# p) (I# n) r
250 | n <# 0# && p ># 6# = '(' : itos n (')' : r)
251 | otherwise = itos n r
253 itos :: Int# -> String -> String
257 in if n'# <# 0# -- minInt?
258 then '-' : itos' (negateInt# (n'# `quotInt#` 10#))
259 (itos' (negateInt# (n'# `remInt#` 10#)) cs)
260 else '-' : itos' n'# cs
261 | otherwise = itos' n# cs
263 itos' :: Int# -> String -> String
265 | n# <# 10# = C# (chr# (ord# '0'# +# n#)) : cs
266 | otherwise = case chr# (ord# '0'# +# (n# `remInt#` 10#)) of { c# ->
267 itos' (n# `quotInt#` 10#) (C# c# : cs) }