Use explicit language extensions & remove extension fields from base.cabal
[ghc-base.git] / GHC / Show.lhs
index 2edd038..6cb8bf3 100644 (file)
-% ------------------------------------------------------------------------------
-% $Id: Show.lhs,v 1.1 2001/06/28 14:15:03 simonmar Exp $
-%
-% (c) The University of Glasgow, 1992-2000
-%
-
-\section{Module @GHC.Show@}
-
-
 \begin{code}
-{-# OPTIONS -fno-implicit-prelude #-}
-
+{-# LANGUAGE NoImplicitPrelude, BangPatterns, MagicHash #-}
+{-# OPTIONS_HADDOCK hide #-}
+
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  GHC.Show
+-- Copyright   :  (c) The University of Glasgow, 1992-2002
+-- License     :  see libraries/base/LICENSE
+-- 
+-- Maintainer  :  cvs-ghc@haskell.org
+-- Stability   :  internal
+-- Portability :  non-portable (GHC Extensions)
+--
+-- The 'Show' class, and related operations.
+--
+-----------------------------------------------------------------------------
+
+-- #hide
 module GHC.Show
-       (
-       Show(..), ShowS,
-
-       -- Instances for Show: (), [], Bool, Ordering, Int, Char
+        (
+        Show(..), ShowS,
 
-       -- Show support code
-       shows, showChar, showString, showParen, showList__, showSpace,
-       showLitChar, protectEsc, 
-       intToDigit, showSignedInt,
+        -- Instances for Show: (), [], Bool, Ordering, Int, Char
 
-       -- Character operations
-       isAscii, isLatin1, isControl, isPrint, isSpace, isUpper,
-       isLower, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum,
-       toUpper, toLower,
-       asciiTab,
+        -- Show support code
+        shows, showChar, showString, showMultiLineString,
+        showParen, showList__, showSpace,
+        showLitChar, showLitString, protectEsc,
+        intToDigit, showSignedInt,
+        appPrec, appPrec1,
 
-       -- String operations
-       lines, unlines, words, unwords
-  ) 
-       where
+        -- Character operations
+        asciiTab,
+  )
+        where
 
-import {-# SOURCE #-} GHC.Err ( error )
 import GHC.Base
-import GHC.Tup
-import GHC.Maybe
-import GHC.List        ( (!!), break, dropWhile
-#ifdef USE_REPORT_PRELUDE
-                , concatMap, foldr1
-#endif
-                )
+import Data.Maybe
+import GHC.List ((!!), foldr1, break)
 \end{code}
 
 
 
 %*********************************************************
-%*                                                     *
+%*                                                      *
 \subsection{The @Show@ class}
-%*                                                     *
+%*                                                      *
 %*********************************************************
 
 \begin{code}
+-- | The @shows@ functions return a function that prepends the
+-- output 'String' to an existing 'String'.  This allows constant-time
+-- concatenation of results using function composition.
 type ShowS = String -> String
 
+-- | Conversion of values to readable 'String's.
+--
+-- Minimal complete definition: 'showsPrec' or 'show'.
+--
+-- Derived instances of 'Show' have the following properties, which
+-- are compatible with derived instances of 'Text.Read.Read':
+--
+-- * The result of 'show' is a syntactically correct Haskell
+--   expression containing only constants, given the fixity
+--   declarations in force at the point where the type is declared.
+--   It contains only the constructor names defined in the data type,
+--   parentheses, and spaces.  When labelled constructor fields are
+--   used, braces, commas, field names, and equal signs are also used.
+--
+-- * If the constructor is defined to be an infix operator, then
+--   'showsPrec' will produce infix applications of the constructor.
+--
+-- * the representation will be enclosed in parentheses if the
+--   precedence of the top-level constructor in @x@ is less than @d@
+--   (associativity is ignored).  Thus, if @d@ is @0@ then the result
+--   is never surrounded in parentheses; if @d@ is @11@ it is always
+--   surrounded in parentheses, unless it is an atomic expression.
+--
+-- * If the constructor is defined using record syntax, then 'show'
+--   will produce the record-syntax form, with the fields given in the
+--   same order as the original declaration.
+--
+-- For example, given the declarations
+--
+-- > infixr 5 :^:
+-- > data Tree a =  Leaf a  |  Tree a :^: Tree a
+--
+-- the derived instance of 'Show' is equivalent to
+--
+-- > instance (Show a) => Show (Tree a) where
+-- >
+-- >        showsPrec d (Leaf m) = showParen (d > app_prec) $
+-- >             showString "Leaf " . showsPrec (app_prec+1) m
+-- >          where app_prec = 10
+-- >
+-- >        showsPrec d (u :^: v) = showParen (d > up_prec) $
+-- >             showsPrec (up_prec+1) u . 
+-- >             showString " :^: "      .
+-- >             showsPrec (up_prec+1) v
+-- >          where up_prec = 5
+--
+-- Note that right-associativity of @:^:@ is ignored.  For example,
+--
+-- * @'show' (Leaf 1 :^: Leaf 2 :^: Leaf 3)@ produces the string
+--   @\"Leaf 1 :^: (Leaf 2 :^: Leaf 3)\"@.
+
 class  Show a  where
-    showsPrec :: Int -> a -> ShowS
+    -- | Convert a value to a readable 'String'.
+    --
+    -- 'showsPrec' should satisfy the law
+    --
+    -- > showsPrec d x r ++ s  ==  showsPrec d x (r ++ s)
+    --
+    -- Derived instances of 'Text.Read.Read' and 'Show' satisfy the following:
+    --
+    -- * @(x,\"\")@ is an element of
+    --   @('Text.Read.readsPrec' d ('showsPrec' d x \"\"))@.
+    --
+    -- That is, 'Text.Read.readsPrec' parses the string produced by
+    -- 'showsPrec', and delivers the value that 'showsPrec' started with.
+
+    showsPrec :: Int    -- ^ the operator precedence of the enclosing
+                        -- context (a number from @0@ to @11@).
+                        -- Function application has precedence @10@.
+              -> a      -- ^ the value to be converted to a 'String'
+              -> ShowS
+
+    -- | A specialised variant of 'showsPrec', using precedence context
+    -- zero, and returning an ordinary 'String'.
     show      :: a   -> String
+
+    -- | The method 'showList' is provided to allow the programmer to
+    -- give a specialised way of showing lists of values.
+    -- For example, this is used by the predefined 'Show' instance of
+    -- the 'Char' type, where values of type 'String' should be shown
+    -- in double quotes, rather than between square brackets.
     showList  :: [a] -> ShowS
 
     showsPrec _ x s = show x ++ s
@@ -69,12 +147,18 @@ showList__ showx (x:xs) s = '[' : showx x (showl xs)
   where
     showl []     = ']' : s
     showl (y:ys) = ',' : showx y (showl ys)
+
+appPrec, appPrec1 :: Int
+        -- Use unboxed stuff because we don't have overloaded numerics yet
+appPrec = I# 10#        -- Precedence of application:
+                        --   one more than the maximum operator precedence of 9
+appPrec1 = I# 11#       -- appPrec + 1
 \end{code}
 
 %*********************************************************
-%*                                                     *
+%*                                                      *
 \subsection{Simple Instances}
-%*                                                     *
+%*                                                      *
 %*********************************************************
 
 \begin{code}
@@ -98,93 +182,134 @@ instance  Show Char  where
     showsPrec _ '\'' = showString "'\\''"
     showsPrec _ c    = showChar '\'' . showLitChar c . showChar '\''
 
-    showList cs = showChar '"' . showl cs
-                where showl ""       s = showChar '"' s
-                      showl ('"':xs) s = showString "\\\"" (showl xs s)
-                      showl (x:xs)   s = showLitChar x (showl xs s)
-               -- Making 's' an explicit parameter makes it clear to GHC
-               -- that showl has arity 2, which avoids it allocating an extra lambda
-               -- The sticking point is the recursive call to (showl xs), which
-               -- it can't figure out would be ok with arity 2.
+    showList cs = showChar '"' . showLitString cs . showChar '"'
 
 instance Show Int where
     showsPrec = showSignedInt
 
 instance Show a => Show (Maybe a) where
     showsPrec _p Nothing s = showString "Nothing" s
-    showsPrec (I# p#) (Just x) s
-                          = (showParen (p# >=# 10#) $ 
-                            showString "Just " . 
-                            showsPrec (I# 10#) x) s
-
-instance (Show a, Show b) => Show (Either a b) where
-    showsPrec (I# p#) e s =
-       (showParen (p# >=# 10#) $
-        case e of
-         Left  a -> showString "Left "  . showsPrec (I# 10#) a
-        Right b -> showString "Right " . showsPrec (I# 10#) b)
-       s
-
+    showsPrec p (Just x) s
+                          = (showParen (p > appPrec) $ 
+                             showString "Just " . 
+                             showsPrec appPrec1 x) s
 \end{code}
 
 
 %*********************************************************
-%*                                                     *
+%*                                                      *
 \subsection{Show instances for the first few tuples
-%*                                                     *
+%*                                                      *
 %*********************************************************
 
 \begin{code}
 -- The explicit 's' parameters are important
 -- Otherwise GHC thinks that "shows x" might take a lot of work to compute
 -- and generates defns like
---     showsPrec _ (x,y) = let sx = shows x; sy = shows y in
---                         \s -> showChar '(' (sx (showChar ',' (sy (showChar ')' s))))
+--      showsPrec _ (x,y) = let sx = shows x; sy = shows y in
+--                          \s -> showChar '(' (sx (showChar ',' (sy (showChar ')' s))))
 
 instance  (Show a, Show b) => Show (a,b)  where
-    showsPrec _ (x,y) s = (showChar '(' . shows x . showChar ',' .
-                                          shows y . showChar ')') 
-                         s
+  showsPrec _ (a,b) s = show_tuple [shows a, shows b] s
 
 instance (Show a, Show b, Show c) => Show (a, b, c) where
-    showsPrec _ (x,y,z) s = (showChar '(' . shows x . showChar ',' .
-                                           shows y . showChar ',' .
-                                           shows z . showChar ')')
-                           s
+  showsPrec _ (a,b,c) s = show_tuple [shows a, shows b, shows c] s
 
 instance (Show a, Show b, Show c, Show d) => Show (a, b, c, d) where
-    showsPrec _ (w,x,y,z) s = (showChar '(' . shows w . showChar ',' .
-                                             shows x . showChar ',' .
-                                             shows y . showChar ',' .
-                                             shows z . showChar ')')
-                             s
+  showsPrec _ (a,b,c,d) s = show_tuple [shows a, shows b, shows c, shows d] s
 
 instance (Show a, Show b, Show c, Show d, Show e) => Show (a, b, c, d, e) where
-    showsPrec _ (v,w,x,y,z) s = (showChar '(' . shows v . showChar ',' .
-                                               shows w . showChar ',' .
-                                               shows x . showChar ',' .
-                                               shows y . showChar ',' .
-                                               shows z . showChar ')') 
-                               s
+  showsPrec _ (a,b,c,d,e) s = show_tuple [shows a, shows b, shows c, shows d, shows e] s
+
+instance (Show a, Show b, Show c, Show d, Show e, Show f) => Show (a,b,c,d,e,f) where
+  showsPrec _ (a,b,c,d,e,f) s = show_tuple [shows a, shows b, shows c, shows d, shows e, shows f] s
+
+instance (Show a, Show b, Show c, Show d, Show e, Show f, Show g)
+        => Show (a,b,c,d,e,f,g) where
+  showsPrec _ (a,b,c,d,e,f,g) s 
+        = show_tuple [shows a, shows b, shows c, shows d, shows e, shows f, shows g] s
+
+instance (Show a, Show b, Show c, Show d, Show e, Show f, Show g, Show h)
+         => Show (a,b,c,d,e,f,g,h) where
+  showsPrec _ (a,b,c,d,e,f,g,h) s 
+        = show_tuple [shows a, shows b, shows c, shows d, shows e, shows f, shows g, shows h] s
+
+instance (Show a, Show b, Show c, Show d, Show e, Show f, Show g, Show h, Show i)
+         => Show (a,b,c,d,e,f,g,h,i) where
+  showsPrec _ (a,b,c,d,e,f,g,h,i) s 
+        = show_tuple [shows a, shows b, shows c, shows d, shows e, shows f, shows g, shows h, 
+                      shows i] s
+
+instance (Show a, Show b, Show c, Show d, Show e, Show f, Show g, Show h, Show i, Show j)
+         => Show (a,b,c,d,e,f,g,h,i,j) where
+  showsPrec _ (a,b,c,d,e,f,g,h,i,j) s 
+        = show_tuple [shows a, shows b, shows c, shows d, shows e, shows f, shows g, shows h, 
+                      shows i, shows j] s
+
+instance (Show a, Show b, Show c, Show d, Show e, Show f, Show g, Show h, Show i, Show j, Show k)
+         => Show (a,b,c,d,e,f,g,h,i,j,k) where
+  showsPrec _ (a,b,c,d,e,f,g,h,i,j,k) s 
+        = show_tuple [shows a, shows b, shows c, shows d, shows e, shows f, shows g, shows h, 
+                      shows i, shows j, shows k] s
+
+instance (Show a, Show b, Show c, Show d, Show e, Show f, Show g, Show h, Show i, Show j, Show k,
+          Show l)
+         => Show (a,b,c,d,e,f,g,h,i,j,k,l) where
+  showsPrec _ (a,b,c,d,e,f,g,h,i,j,k,l) s 
+        = show_tuple [shows a, shows b, shows c, shows d, shows e, shows f, shows g, shows h, 
+                      shows i, shows j, shows k, shows l] s
+
+instance (Show a, Show b, Show c, Show d, Show e, Show f, Show g, Show h, Show i, Show j, Show k,
+          Show l, Show m)
+         => Show (a,b,c,d,e,f,g,h,i,j,k,l,m) where
+  showsPrec _ (a,b,c,d,e,f,g,h,i,j,k,l,m) s 
+        = show_tuple [shows a, shows b, shows c, shows d, shows e, shows f, shows g, shows h, 
+                      shows i, shows j, shows k, shows l, shows m] s
+
+instance (Show a, Show b, Show c, Show d, Show e, Show f, Show g, Show h, Show i, Show j, Show k,
+          Show l, Show m, Show n)
+         => Show (a,b,c,d,e,f,g,h,i,j,k,l,m,n) where
+  showsPrec _ (a,b,c,d,e,f,g,h,i,j,k,l,m,n) s 
+        = show_tuple [shows a, shows b, shows c, shows d, shows e, shows f, shows g, shows h, 
+                      shows i, shows j, shows k, shows l, shows m, shows n] s
+
+instance (Show a, Show b, Show c, Show d, Show e, Show f, Show g, Show h, Show i, Show j, Show k,
+          Show l, Show m, Show n, Show o)
+         => Show (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) where
+  showsPrec _ (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) s 
+        = show_tuple [shows a, shows b, shows c, shows d, shows e, shows f, shows g, shows h, 
+                      shows i, shows j, shows k, shows l, shows m, shows n, shows o] s
+
+show_tuple :: [ShowS] -> ShowS
+show_tuple ss = showChar '('
+              . foldr1 (\s r -> s . showChar ',' . r) ss
+              . showChar ')'
 \end{code}
 
 
 %*********************************************************
-%*                                                     *
+%*                                                      *
 \subsection{Support code for @Show@}
-%*                                                     *
+%*                                                      *
 %*********************************************************
 
 \begin{code}
+-- | equivalent to 'showsPrec' with a precedence of 0.
 shows           :: (Show a) => a -> ShowS
 shows           =  showsPrec zeroInt
 
+-- | utility function converting a 'Char' to a show function that
+-- simply prepends the character unchanged.
 showChar        :: Char -> ShowS
 showChar        =  (:)
 
+-- | utility function converting a 'String' to a show function that
+-- simply prepends the string unchanged.
 showString      :: String -> ShowS
 showString      =  (++)
 
+-- | utility function that surrounds the inner show function with
+-- parentheses when the 'Bool' parameter is 'True'.
 showParen       :: Bool -> ShowS -> ShowS
 showParen b p   =  if b then showChar '(' . p . showChar ')' else p
 
@@ -195,39 +320,92 @@ showSpace = {-showChar ' '-} \ xs -> ' ' : xs
 Code specific for characters
 
 \begin{code}
-showLitChar               :: Char -> ShowS
-showLitChar c s | c > '\DEL' =  showChar '\\' (protectEsc isDigit (shows (ord c)) s)
-showLitChar '\DEL'        s =  showString "\\DEL" s
-showLitChar '\\'          s =  showString "\\\\" s
+-- | Convert a character to a string using only printable characters,
+-- using Haskell source-language escape conventions.  For example:
+--
+-- > showLitChar '\n' s  =  "\\n" ++ s
+--
+showLitChar                :: Char -> ShowS
+showLitChar c s | c > '\DEL' =  showChar '\\' (protectEsc isDec (shows (ord c)) s)
+showLitChar '\DEL'         s =  showString "\\DEL" s
+showLitChar '\\'           s =  showString "\\\\" s
 showLitChar c s | c >= ' '   =  showChar c s
-showLitChar '\a'          s =  showString "\\a" s
-showLitChar '\b'          s =  showString "\\b" s
-showLitChar '\f'          s =  showString "\\f" s
-showLitChar '\n'          s =  showString "\\n" s
-showLitChar '\r'          s =  showString "\\r" s
-showLitChar '\t'          s =  showString "\\t" s
-showLitChar '\v'          s =  showString "\\v" s
-showLitChar '\SO'         s =  protectEsc (== 'H') (showString "\\SO") s
-showLitChar c             s =  showString ('\\' : asciiTab!!ord c) s
-       -- I've done manual eta-expansion here, becuase otherwise it's
-       -- impossible to stop (asciiTab!!ord) getting floated out as an MFE
+showLitChar '\a'           s =  showString "\\a" s
+showLitChar '\b'           s =  showString "\\b" s
+showLitChar '\f'           s =  showString "\\f" s
+showLitChar '\n'           s =  showString "\\n" s
+showLitChar '\r'           s =  showString "\\r" s
+showLitChar '\t'           s =  showString "\\t" s
+showLitChar '\v'           s =  showString "\\v" s
+showLitChar '\SO'          s =  protectEsc (== 'H') (showString "\\SO") s
+showLitChar c              s =  showString ('\\' : asciiTab!!ord c) s
+        -- I've done manual eta-expansion here, becuase otherwise it's
+        -- impossible to stop (asciiTab!!ord) getting floated out as an MFE
+
+showLitString :: String -> ShowS
+-- | Same as 'showLitChar', but for strings
+-- It converts the string to a string using Haskell escape conventions
+-- for non-printable characters. Does not add double-quotes around the
+-- whole thing; the caller should do that.
+-- The main difference from showLitChar (apart from the fact that the
+-- argument is a string not a list) is that we must escape double-quotes 
+showLitString []         s = s
+showLitString ('"' : cs) s = showString "\\\"" (showLitString cs s)
+showLitString (c   : cs) s = showLitChar c (showLitString cs s)
+   -- Making 's' an explicit parameter makes it clear to GHC that
+   -- showLitString has arity 2, which avoids it allocating an extra lambda
+   -- The sticking point is the recursive call to (showLitString cs), which
+   -- it can't figure out would be ok with arity 2.
+
+showMultiLineString :: String -> [String]
+-- | Like 'showLitString' (expand escape characters using Haskell
+-- escape conventions), but 
+--   * break the string into multiple lines
+--   * wrap the entire thing in double quotes
+-- Example:  @breakMultiLineString "hello\ngoodbye\nblah"@ 
+-- returns   @["\"hello\\", "\\goodbye\\", "\\blah\"" ]@
+-- where those "\\" are really just a single backslash
+-- (but I'm writing them here as Haskell literals)
+showMultiLineString str
+  = go '\"' str
+  where
+    go ch s = case break (== '\n') s of
+                (l, _:s'@(_:_)) -> (ch : showLitString l "\\") : go '\\' s'
+                (l, _)          -> [ch : showLitString l "\""]
+
+isDec :: Char -> Bool
+isDec c = c >= '0' && c <= '9'
 
 protectEsc :: (Char -> Bool) -> ShowS -> ShowS
-protectEsc p f            = f . cont
-                            where cont s@(c:_) | p c = "\\&" ++ s
-                                  cont s             = s
+protectEsc p f             = f . cont
+                             where cont s@(c:_) | p c = "\\&" ++ s
+                                   cont s             = s
 
-intToDigit :: Int -> Char
-intToDigit (I# i)
-    | i >=# 0#  && i <=#  9# =  unsafeChr (ord '0' `plusInt` I# i)
-    | i >=# 10# && i <=# 15# =  unsafeChr (ord 'a' `minusInt` I# 10# `plusInt` I# i)
-    | otherwise                  =  error ("Char.intToDigit: not a digit " ++ show (I# i))
 
+asciiTab :: [String]
+asciiTab = -- Using an array drags in the array module.  listArray ('\NUL', ' ')
+           ["NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
+            "BS",  "HT",  "LF",  "VT",  "FF",  "CR",  "SO",  "SI", 
+            "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
+            "CAN", "EM",  "SUB", "ESC", "FS",  "GS",  "RS",  "US", 
+            "SP"] 
 \end{code}
 
 Code specific for Ints.
 
 \begin{code}
+-- | Convert an 'Int' in the range @0@..@15@ to the corresponding single
+-- digit 'Char'.  This function fails on other inputs, and generates
+-- lower-case hexadecimal digits.
+intToDigit :: Int -> Char
+intToDigit (I# i)
+    | i >=# 0#  && i <=#  9# =  unsafeChr (ord '0' `plusInt` I# i)
+    | i >=# 10# && i <=# 15# =  unsafeChr (ord 'a' `minusInt` ten `plusInt` I# i)
+    | otherwise           =  error ("Char.intToDigit: not a digit " ++ show (I# i))
+
+ten :: Int
+ten = I# 10#
+
 showSignedInt :: Int -> Int -> ShowS
 showSignedInt (I# p) (I# n) r
     | n <# 0# && p ># 6# = '(' : itos n (')' : r)
@@ -235,144 +413,19 @@ showSignedInt (I# p) (I# n) r
 
 itos :: Int# -> String -> String
 itos n# cs
-    | n# <# 0# = let
-        n'# = negateInt# n#
-        in if n'# <# 0# -- minInt?
-            then '-' : itos' (negateInt# (n'# `quotInt#` 10#))
-                             (itos' (negateInt# (n'# `remInt#` 10#)) cs)
-            else '-' : itos' n'# cs
+    | n# <# 0# =
+        let !(I# minInt#) = minInt in
+        if n# ==# minInt#
+                -- negateInt# minInt overflows, so we can't do that:
+           then '-' : itos' (negateInt# (n# `quotInt#` 10#))
+                             (itos' (negateInt# (n# `remInt#` 10#)) cs)
+           else '-' : itos' (negateInt# n#) cs
     | otherwise = itos' n# cs
     where
     itos' :: Int# -> String -> String
-    itos' n# cs
-        | n# <# 10#  = C# (chr# (ord# '0'# +# n#)) : cs
-        | otherwise = itos' (n# `quotInt#` 10#)
-                            (C# (chr# (ord# '0'# +# (n# `remInt#` 10#))) : cs)
-\end{code}
-
-%*********************************************************
-%*                                                     *
-\subsection{Character stuff}
-%*                                                     *
-%*********************************************************
-
-\begin{code}
-isAscii, isLatin1, isControl, isPrint, isSpace, isUpper,
- isLower, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum,
- isAsciiUpper, isAsciiLower :: Char -> Bool
-isAscii c              =  c <  '\x80'
-isLatin1 c              =  c <= '\xff'
-isControl c            =  c < ' ' || c >= '\DEL' && c <= '\x9f'
-isPrint c              =  not (isControl c)
-
--- isSpace includes non-breaking space
--- Done with explicit equalities both for efficiency, and to avoid a tiresome
--- recursion with GHC.List elem
-isSpace c              =  c == ' '     ||
-                          c == '\t'    ||
-                          c == '\n'    ||
-                          c == '\r'    ||
-                          c == '\f'    ||
-                          c == '\v'    ||
-                          c == '\xa0'
-
--- The upper case ISO characters have the multiplication sign dumped
--- randomly in the middle of the range.  Go figure.
-isUpper c              =  c >= 'A' && c <= 'Z' || 
-                           c >= '\xC0' && c <= '\xD6' ||
-                           c >= '\xD8' && c <= '\xDE'
--- The lower case ISO characters have the division sign dumped
--- randomly in the middle of the range.  Go figure.
-isLower c              =  c >= 'a' && c <= 'z' ||
-                           c >= '\xDF' && c <= '\xF6' ||
-                           c >= '\xF8' && c <= '\xFF'
-isAsciiLower c          =  c >= 'a' && c <= 'z'
-isAsciiUpper c          =  c >= 'A' && c <= 'Z'
-
-isAlpha c              =  isLower c || isUpper c
-isDigit c              =  c >= '0' && c <= '9'
-isOctDigit c           =  c >= '0' && c <= '7'
-isHexDigit c           =  isDigit c || c >= 'A' && c <= 'F' ||
-                                        c >= 'a' && c <= 'f'
-isAlphaNum c           =  isAlpha c || isDigit c
-
--- Case-changing operations
-
-toUpper, toLower       :: Char -> Char
-toUpper c@(C# c#)
-  | isAsciiLower c    = C# (chr# (ord# c# -# 32#))
-  | isAscii c         = c
-    -- fall-through to the slower stuff.
-  | isLower c  && c /= '\xDF' && c /= '\xFF'
-  = unsafeChr (ord c `minusInt` ord 'a' `plusInt` ord 'A')
-  | otherwise
-  = c
-
-
-
-toLower c@(C# c#)
-  | isAsciiUpper c = C# (chr# (ord# c# +# 32#))
-  | isAscii c      = c
-  | isUpper c     = unsafeChr (ord c `minusInt` ord 'A' `plusInt` ord 'a')
-  | otherwise     =  c
-
-asciiTab :: [String]
-asciiTab = -- Using an array drags in the array module.  listArray ('\NUL', ' ')
-          ["NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
-           "BS",  "HT",  "LF",  "VT",  "FF",  "CR",  "SO",  "SI", 
-           "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
-           "CAN", "EM",  "SUB", "ESC", "FS",  "GS",  "RS",  "US", 
-           "SP"] 
+    itos' x# cs'
+        | x# <# 10#  = C# (chr# (ord# '0'# +# x#)) : cs'
+        | otherwise = case chr# (ord# '0'# +# (x# `remInt#` 10#)) of { c# ->
+                      itos' (x# `quotInt#` 10#) (C# c# : cs') }
 \end{code}
 
-%*********************************************************
-%*                                                     *
-\subsection{Functions on strings}
-%*                                                     *
-%*********************************************************
-
-lines breaks a string up into a list of strings at newline characters.
-The resulting strings do not contain newlines.  Similary, words
-breaks a string up into a list of words, which were delimited by
-white space.  unlines and unwords are the inverse operations.
-unlines joins lines with terminating newlines, and unwords joins
-words with separating spaces.
-
-\begin{code}
-lines                  :: String -> [String]
-lines ""               =  []
-lines s                        =  let (l, s') = break (== '\n') s
-                          in  l : case s' of
-                                       []      -> []
-                                       (_:s'') -> lines s''
-
-words                  :: String -> [String]
-words s                        =  case dropWhile {-partain:Char.-}isSpace s of
-                               "" -> []
-                               s' -> w : words s''
-                                     where (w, s'') = 
-                                             break {-partain:Char.-}isSpace s'
-
-unlines                        :: [String] -> String
-#ifdef USE_REPORT_PRELUDE
-unlines                        =  concatMap (++ "\n")
-#else
--- HBC version (stolen)
--- here's a more efficient version
-unlines [] = []
-unlines (l:ls) = l ++ '\n' : unlines ls
-#endif
-
-unwords                        :: [String] -> String
-#ifdef USE_REPORT_PRELUDE
-unwords []             =  ""
-unwords ws             =  foldr1 (\w s -> w ++ ' ':s) ws
-#else
--- HBC version (stolen)
--- here's a more efficient version
-unwords []             =  ""
-unwords [w]            = w
-unwords (w:ws)         = w ++ ' ' : unwords ws
-#endif
-
-\end{code}