From c415cd35368f45739132fc180837fc07f0490921 Mon Sep 17 00:00:00 2001 From: simonpj Date: Tue, 18 May 1999 14:59:24 +0000 Subject: [PATCH] [project @ 1999-05-18 14:59:04 by simonpj] ../compiler/msg_prel --- ghc/lib/exts/GlaExts.lhs | 3 + ghc/lib/exts/NumExts.lhs | 3 +- ghc/lib/misc/PackedString.lhs | 2 +- ghc/lib/misc/Printf.lhs | 2 +- ghc/lib/misc/Util.lhs | 8 +- ghc/lib/posix/PosixFiles.lhs | 2 +- ghc/lib/std/Array.lhs | 1 + ghc/lib/std/Char.lhs | 6 +- ghc/lib/std/IO.lhs | 5 +- ghc/lib/std/Ix.lhs | 160 +++++++---- ghc/lib/std/List.lhs | 1 + ghc/lib/std/Main.hi-boot | 3 +- ghc/lib/std/Numeric.lhs | 1 + ghc/lib/std/PrelAddr.lhs | 1 + ghc/lib/std/PrelArr.lhs | 49 ++-- ghc/lib/std/PrelBase.lhs | 532 ++++++++----------------------------- ghc/lib/std/PrelBounded.lhs | 23 -- ghc/lib/std/PrelConc.lhs | 3 +- ghc/lib/std/PrelEither.lhs | 20 -- ghc/lib/std/PrelEnum.lhs | 317 ++++++++++++++++++++++ ghc/lib/std/PrelErr.hi-boot | 2 +- ghc/lib/std/PrelErr.lhs | 1 - ghc/lib/std/PrelException.hi-boot | 2 +- ghc/lib/std/PrelException.lhs | 4 +- ghc/lib/std/PrelHandle.lhs | 5 +- ghc/lib/std/PrelIOBase.lhs | 3 +- ghc/lib/std/PrelList.lhs | 238 ++++++++++------- ghc/lib/std/PrelMain.lhs | 1 - ghc/lib/std/PrelMaybe.lhs | 25 +- ghc/lib/std/PrelNum.lhs | 68 +++-- ghc/lib/std/PrelNumExtra.lhs | 12 +- ghc/lib/std/PrelPack.hi-boot | 2 +- ghc/lib/std/PrelPack.lhs | 1 + ghc/lib/std/PrelRead.lhs | 5 +- ghc/lib/std/PrelST.lhs | 21 +- ghc/lib/std/PrelShow.lhs | 347 ++++++++++++++++++++++++ ghc/lib/std/PrelTup.lhs | 39 +-- ghc/lib/std/Prelude.lhs | 31 ++- ghc/lib/std/Random.lhs | 1 + ghc/lib/std/Time.lhs | 1 + 40 files changed, 1212 insertions(+), 739 deletions(-) delete mode 100644 ghc/lib/std/PrelBounded.lhs delete mode 100644 ghc/lib/std/PrelEither.lhs create mode 100644 ghc/lib/std/PrelEnum.lhs create mode 100644 ghc/lib/std/PrelShow.lhs diff --git a/ghc/lib/exts/GlaExts.lhs b/ghc/lib/exts/GlaExts.lhs index 2a673e2..050e031 100644 --- a/ghc/lib/exts/GlaExts.lhs +++ b/ghc/lib/exts/GlaExts.lhs @@ -50,6 +50,9 @@ module GlaExts -- the representation of some basic types: Int(..),Addr(..),Word(..),Float(..),Double(..),Integer(..),Char(..), + -- Fusion + build, augment, + -- misc bits trace, diff --git a/ghc/lib/exts/NumExts.lhs b/ghc/lib/exts/NumExts.lhs index a229481..6371651 100644 --- a/ghc/lib/exts/NumExts.lhs +++ b/ghc/lib/exts/NumExts.lhs @@ -31,7 +31,8 @@ import Char (ord, chr) import PreludeBuiltin ord_0 = ord '0' #else -import PrelBase (ord_0, showList__) +import PrelNum ( ord_0 ) +import PrelShow( showList__ ) import GlaExts #endif \end{code} diff --git a/ghc/lib/misc/PackedString.lhs b/ghc/lib/misc/PackedString.lhs index d01473b..ab6e592 100644 --- a/ghc/lib/misc/PackedString.lhs +++ b/ghc/lib/misc/PackedString.lhs @@ -74,7 +74,7 @@ module PackedString ( ) where import GlaExts -import PrelBase ( showList__ ) -- ToDo: better +import PrelShow ( showList__ ) -- ToDo: better import PrelPack ( new_ps_array , freeze_ps_array diff --git a/ghc/lib/misc/Printf.lhs b/ghc/lib/misc/Printf.lhs index d11a539..8a0bb15 100644 --- a/ghc/lib/misc/Printf.lhs +++ b/ghc/lib/misc/Printf.lhs @@ -34,7 +34,7 @@ import PrintfPrims #if defined(__GLASGOW_HASKELL__) import GlaExts import PrelArr (Array(..), ByteArray(..)) -import PrelBase hiding (itos) +import PrelBase #endif data UPrintf = UChar Char | UString String | UInt Int | UInteger Integer | UFloat Float | UDouble Double diff --git a/ghc/lib/misc/Util.lhs b/ghc/lib/misc/Util.lhs index cc48510..791cd6a 100644 --- a/ghc/lib/misc/Util.lhs +++ b/ghc/lib/misc/Util.lhs @@ -201,7 +201,7 @@ nOfThem :: Int -> a -> [a] nOfThem = replicate -- deprecated. lengthExceeds :: [a] -> Int -> Bool - +-- (lengthExceeds xs n) is True if length xs > n [] `lengthExceeds` n = 0 > n (x:xs) `lengthExceeds` n = (1 > n) || (xs `lengthExceeds` (n - 1)) @@ -719,12 +719,6 @@ cmpString (x:xs) (y:ys) = if x == y then cmpString xs ys else GT_ cmpString [] ys = LT_ cmpString xs [] = GT_ - -#ifdef COMPILING_GHC -cmpString _ _ = panic# "cmpString" -#else -cmpString _ _ = error "cmpString" -#endif \end{code} \begin{code} diff --git a/ghc/lib/posix/PosixFiles.lhs b/ghc/lib/posix/PosixFiles.lhs index 9795733..9b75334 100644 --- a/ghc/lib/posix/PosixFiles.lhs +++ b/ghc/lib/posix/PosixFiles.lhs @@ -77,7 +77,7 @@ import CString ( packStringIO, allocChars, ) import Addr import CCall -import PrelBase +import PrelBase hiding( append ) import ByteArray import PosixErr diff --git a/ghc/lib/std/Array.lhs b/ghc/lib/std/Array.lhs index b5dfbf9..715dc73 100644 --- a/ghc/lib/std/Array.lhs +++ b/ghc/lib/std/Array.lhs @@ -40,6 +40,7 @@ module Array import Ix import PrelList +import PrelShow import PrelArr -- Most of the hard work is done here import PrelBase diff --git a/ghc/lib/std/Char.lhs b/ghc/lib/std/Char.lhs index b00345d..213d8f7 100644 --- a/ghc/lib/std/Char.lhs +++ b/ghc/lib/std/Char.lhs @@ -33,7 +33,9 @@ module Char ) where import PrelBase +import PrelShow +import PrelEnum +import PrelNum import PrelRead (readLitChar, lexLitChar, digitToInt) -import {-# SOURCE #-} PrelErr ( error ) - +import PrelErr ( error ) \end{code} diff --git a/ghc/lib/std/IO.lhs b/ghc/lib/std/IO.lhs index 5b5aef6..c05e200 100644 --- a/ghc/lib/std/IO.lhs +++ b/ghc/lib/std/IO.lhs @@ -108,9 +108,8 @@ import PrelHandle -- much of the real stuff is in here import PrelRead ( readParen, Read(..), reads, lex, readIO ) ---import PrelNum ( toInteger ) -import PrelBounded () -- Bounded Int instance. -import PrelEither ( Either(..) ) +import PrelShow +import PrelMaybe ( Either(..) ) import PrelAddr ( Addr(..), nullAddr ) import PrelArr ( ByteArray ) import PrelPack ( unpackNBytesAccST ) diff --git a/ghc/lib/std/Ix.lhs b/ghc/lib/std/Ix.lhs index 5f121d8..1b07831 100644 --- a/ghc/lib/std/Ix.lhs +++ b/ghc/lib/std/Ix.lhs @@ -32,6 +32,10 @@ module Ix import {-# SOURCE #-} PrelErr ( error ) import PrelTup import PrelBase +import PrelList( null ) +import PrelEnum +import PrelShow +import PrelNum \end{code} %********************************************************* @@ -43,10 +47,14 @@ import PrelBase \begin{code} class (Ord a) => Ix a where range :: (a,a) -> [a] - index :: (a,a) -> a -> Int + index, unsafeIndex :: (a,a) -> a -> Int inRange :: (a,a) -> a -> Bool -\end{code} + -- Must specify one of index, unsafeIndex + index b i | inRange b i = unsafeIndex b i + | otherwise = error "Error in array index" + unsafeIndex b i = index b i +\end{code} %********************************************************* %* * @@ -55,43 +63,69 @@ class (Ord a) => Ix a where %********************************************************* \begin{code} +-- abstract these errors from the relevant index functions so that +-- the guts of the function will be small enough to inline. + +{-# NOINLINE indexError #-} +indexError :: Show a => (a,a) -> a -> String -> b +indexError rng i tp + = error (showString "Ix{" . showString tp . showString "}.index: Index " . + showParen True (showsPrec 0 i) . + showString " out of range " $ + showParen True (showsPrec 0 rng) "") + +---------------------------------------------------------------------- instance Ix Char where range (m,n) | m <= n = [m..n] | otherwise = [] - index b@(m,_) i - | inRange b i = fromEnum i - fromEnum m - | otherwise = indexError i b "Char" + + unsafeIndex (m,n) i = fromEnum i - fromEnum m + + index b i | inRange b i = unsafeIndex b i + | otherwise = indexError b i "Char" + inRange (m,n) i = m <= i && i <= n +---------------------------------------------------------------------- instance Ix Int where range (m,n) | m <= n = [m..n] | otherwise = [] - index b@(m,_) i - | inRange b i = i - m - | otherwise = indexError i b "Int" + + unsafeIndex (m,n) i = i - m + + index b i | inRange b i = unsafeIndex b i + | otherwise = indexError b i "Int" + inRange (m,n) i = m <= i && i <= n --- abstract these errors from the relevant index functions so that --- the guts of the function will be small enough to inline. -{-# NOINLINE indexError #-} -indexError :: Show a => a -> (a,a) -> String -> b -indexError i rng tp - = error (showString "Ix{" . showString tp . showString "}.index: Index " . - showParen True (showsPrec 0 i) . - showString " out of range " $ - showParen True (showsPrec 0 rng) "") +---------------------------------------------------------------------- +instance Ix Integer where + range (m,n) + | m <= n = [m..n] + | otherwise = [] + + unsafeIndex (m,n) i = fromInteger (i - m) + + index b i | inRange b i = unsafeIndex b i + | otherwise = indexError b i "Integer" + + inRange (m,n) i = m <= i && i <= n --- Integer instance is in PrelNum ---------------------------------------------------------------------- instance Ix Bool where -- as derived range (l,u) | l <= u = map toEnum [fromEnum l .. fromEnum u] | otherwise = [] - index (l,_) i = fromEnum i - fromEnum l + + unsafeIndex (l,_) i = fromEnum i - fromEnum l + + index b i | inRange b i = unsafeIndex b i + | otherwise = indexError b i "Bool" + inRange (l,u) i = fromEnum i >= fromEnum l && fromEnum i <= fromEnum u ---------------------------------------------------------------------- @@ -99,47 +133,62 @@ instance Ix Ordering where -- as derived range (l,u) | l <= u = map toEnum [fromEnum l .. fromEnum u] | otherwise = [] - index (l,_) i = fromEnum i - fromEnum l + unsafeIndex (l,_) i = fromEnum i - fromEnum l + index b i | inRange b i = unsafeIndex b i + | otherwise = indexError b i "Ordering" inRange (l,u) i = fromEnum i >= fromEnum l && fromEnum i <= fromEnum u ---------------------------------------------------------------------- instance Ix () where {-# INLINE range #-} range ((), ()) = [()] - {-# INLINE index #-} - index ((), ()) () = 0 + {-# INLINE unsafeIndex #-} + unsafeIndex ((), ()) () = 0 {-# INLINE inRange #-} inRange ((), ()) () = True + {-# INLINE index #-} + index b i = unsafeIndex b i + ---------------------------------------------------------------------- instance (Ix a, Ix b) => Ix (a, b) where -- as derived + {-# SPECIALISE instance Ix (Int,Int) #-} + {- INLINE range #-} range ((l1,l2),(u1,u2)) = [ (i1,i2) | i1 <- range (l1,u1), i2 <- range (l2,u2) ] - {- INLINE index #-} - index ((l1,l2),(u1,u2)) (i1,i2) = - index (l1,u1) i1 * rangeSize (l2,u2) + index (l2,u2) i2 + {- INLINE unsafeIndex #-} + unsafeIndex ((l1,l2),(u1,u2)) (i1,i2) = + unsafeIndex (l1,u1) i1 * unsafeRangeSize (l2,u2) + unsafeIndex (l2,u2) i2 {- INLINE inRange #-} inRange ((l1,l2),(u1,u2)) (i1,i2) = inRange (l1,u1) i1 && inRange (l2,u2) i2 + -- Default method for index + +---------------------------------------------------------------------- instance (Ix a1, Ix a2, Ix a3) => Ix (a1,a2,a3) where + {-# SPECIALISE instance Ix (Int,Int,Int) #-} + range ((l1,l2,l3),(u1,u2,u3)) = [(i1,i2,i3) | i1 <- range (l1,u1), i2 <- range (l2,u2), i3 <- range (l3,u3)] - index ((l1,l2,l3),(u1,u2,u3)) (i1,i2,i3) = - index (l3,u3) i3 + rangeSize (l3,u3) * ( - index (l2,u2) i2 + rangeSize (l2,u2) * ( - index (l1,u1) i1)) + unsafeIndex ((l1,l2,l3),(u1,u2,u3)) (i1,i2,i3) = + unsafeIndex (l3,u3) i3 + unsafeRangeSize (l3,u3) * ( + unsafeIndex (l2,u2) i2 + unsafeRangeSize (l2,u2) * ( + unsafeIndex (l1,u1) i1)) inRange ((l1,l2,l3),(u1,u2,u3)) (i1,i2,i3) = inRange (l1,u1) i1 && inRange (l2,u2) i2 && inRange (l3,u3) i3 + -- Default method for index + +---------------------------------------------------------------------- instance (Ix a1, Ix a2, Ix a3, Ix a4) => Ix (a1,a2,a3,a4) where range ((l1,l2,l3,l4),(u1,u2,u3,u4)) = [(i1,i2,i3,i4) | i1 <- range (l1,u1), @@ -147,16 +196,18 @@ instance (Ix a1, Ix a2, Ix a3, Ix a4) => Ix (a1,a2,a3,a4) where i3 <- range (l3,u3), i4 <- range (l4,u4)] - index ((l1,l2,l3,l4),(u1,u2,u3,u4)) (i1,i2,i3,i4) = - index (l4,u4) i4 + rangeSize (l4,u4) * ( - index (l3,u3) i3 + rangeSize (l3,u3) * ( - index (l2,u2) i2 + rangeSize (l2,u2) * ( - index (l1,u1) i1))) + unsafeIndex ((l1,l2,l3,l4),(u1,u2,u3,u4)) (i1,i2,i3,i4) = + unsafeIndex (l4,u4) i4 + unsafeRangeSize (l4,u4) * ( + unsafeIndex (l3,u3) i3 + unsafeRangeSize (l3,u3) * ( + unsafeIndex (l2,u2) i2 + unsafeRangeSize (l2,u2) * ( + unsafeIndex (l1,u1) i1))) inRange ((l1,l2,l3,l4),(u1,u2,u3,u4)) (i1,i2,i3,i4) = inRange (l1,u1) i1 && inRange (l2,u2) i2 && inRange (l3,u3) i3 && inRange (l4,u4) i4 + -- Default method for index + instance (Ix a1, Ix a2, Ix a3, Ix a4, Ix a5) => Ix (a1,a2,a3,a4,a5) where range ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) = [(i1,i2,i3,i4,i5) | i1 <- range (l1,u1), @@ -165,17 +216,19 @@ instance (Ix a1, Ix a2, Ix a3, Ix a4, Ix a5) => Ix (a1,a2,a3,a4,a5) where i4 <- range (l4,u4), i5 <- range (l5,u5)] - index ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) (i1,i2,i3,i4,i5) = - index (l5,u5) i5 + rangeSize (l5,u5) * ( - index (l4,u4) i4 + rangeSize (l4,u4) * ( - index (l3,u3) i3 + rangeSize (l3,u3) * ( - index (l2,u2) i2 + rangeSize (l2,u2) * ( - index (l1,u1) i1)))) + unsafeIndex ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) (i1,i2,i3,i4,i5) = + unsafeIndex (l5,u5) i5 + unsafeRangeSize (l5,u5) * ( + unsafeIndex (l4,u4) i4 + unsafeRangeSize (l4,u4) * ( + unsafeIndex (l3,u3) i3 + unsafeRangeSize (l3,u3) * ( + unsafeIndex (l2,u2) i2 + unsafeRangeSize (l2,u2) * ( + unsafeIndex (l1,u1) i1)))) inRange ((l1,l2,l3,l4,l5),(u1,u2,u3,u4,u5)) (i1,i2,i3,i4,i5) = inRange (l1,u1) i1 && inRange (l2,u2) i2 && inRange (l3,u3) i3 && inRange (l4,u4) i4 && inRange (l5,u5) i5 + + -- Default method for index \end{code} %******************************************************** @@ -185,16 +238,27 @@ instance (Ix a1, Ix a2, Ix a3, Ix a4, Ix a5) => Ix (a1,a2,a3,a4,a5) where %******************************************************** The @rangeSize@ operator returns the number of elements -in the range for an @Ix@ pair: +in the range for an @Ix@ pair. \begin{code} +{-# SPECIALISE unsafeRangeSize :: (Int,Int) -> Int #-} +{-# SPECIALISE unsafeRangeSize :: ((Int,Int),(Int,Int)) -> Int #-} +unsafeRangeSize :: (Ix a) => (a,a) -> Int +unsafeRangeSize b@(l,h) = unsafeIndex b h + 1 + {-# SPECIALISE rangeSize :: (Int,Int) -> Int #-} +{-# SPECIALISE rangeSize :: ((Int,Int),(Int,Int)) -> Int #-} rangeSize :: (Ix a) => (a,a) -> Int -rangeSize b@(l,h) - | l > h || isnull (range b) = 0 - | otherwise = index b h + 1 - where - isnull [] = True - isnull _ = False - +rangeSize b@(l,h) | inRange b h = unsafeIndex b h + 1 + | otherwise = 0 + +-- Note that the following is NOT right +-- rangeSize (l,h) | l <= h = index b h + 1 +-- | otherwise = 0 +-- +-- Because it might be the case that l PrelIOBase.IO a; -- wish this could be __o. KSW 1999-04. + diff --git a/ghc/lib/std/Numeric.lhs b/ghc/lib/std/Numeric.lhs index f38e426..a0365e8 100644 --- a/ghc/lib/std/Numeric.lhs +++ b/ghc/lib/std/Numeric.lhs @@ -36,6 +36,7 @@ module Numeric import PrelBase import PrelMaybe +import PrelShow import PrelArr import PrelNum import PrelNumExtra diff --git a/ghc/lib/std/PrelAddr.lhs b/ghc/lib/std/PrelAddr.lhs index 0c6e2a3..c0b5939 100644 --- a/ghc/lib/std/PrelAddr.lhs +++ b/ghc/lib/std/PrelAddr.lhs @@ -22,6 +22,7 @@ module PrelAddr ( import PrelGHC import PrelBase +import PrelShow import PrelCCall \end{code} diff --git a/ghc/lib/std/PrelArr.lhs b/ghc/lib/std/PrelArr.lhs index b8b1b10..c0da09c 100644 --- a/ghc/lib/std/PrelArr.lhs +++ b/ghc/lib/std/PrelArr.lhs @@ -119,34 +119,30 @@ bounds (Array b _) = b case (indexArray# arr# n#) of (# v #) -> v -#ifdef USE_FOLDR_BUILD {-# INLINE array #-} -#endif -array ixs ivs = - runST ( ST $ \ s -> - case (newArray ixs arrEleBottom) of { ST new_array_thing -> - case (new_array_thing s) of { (# s#, arr@(MutableArray _ arr#) #) -> - let - fill_in s1# [] = s1# - fill_in s1# ((i,v) : is) = - case (index ixs i) of { I# n# -> - case writeArray# arr# n# v s1# of { s2# -> - fill_in s2# is }} - in - - case (fill_in s# ivs) of { s1# -> - case (freezeArray arr) of { ST freeze_array_thing -> - freeze_array_thing s1# }}}}) +array ixs ivs + = case rangeSize ixs of { I# n -> + runST ( ST $ \ s1 -> + case newArray# n arrEleBottom s1 of { (# s2, marr #) -> + foldr (fill ixs marr) (done ixs marr) ivs s2 + })} + +fill :: Ix ix => (ix,ix) -> MutableArray# s elt + -> (ix,elt) -> STRep s a -> STRep s a +{-# INLINE fill #-} +fill ixs marr (i,v) next = \s1 -> case index ixs i of { I# n -> + case writeArray# marr n v s1 of { s2 -> + next s2 }} + +done :: Ix ix => (ix,ix) -> MutableArray# s elt + -> STRep s (Array ix elt) +{-# INLINE done #-} +done ixs marr = \s1 -> case unsafeFreezeArray# marr s1 of { (# s2, arr #) -> + (# s2, Array ixs arr #) } arrEleBottom :: a arrEleBottom = error "(Array.!): undefined array element" -fill_it_in :: Ix ix => MutableArray s ix elt -> [(ix, elt)] -> ST s () -fill_it_in arr lst - = foldr fill_one_in (return ()) lst - where -- **** STRICT **** (but that's OK...) - fill_one_in (i, v) rst - = writeArray arr i v >> rst ----------------------------------------------------------------------- -- these also go better with magic: (//), accum, accumArray @@ -160,6 +156,13 @@ old_array // ivs freezeArray arr ) +fill_it_in :: Ix ix => MutableArray s ix elt -> [(ix, elt)] -> ST s () +fill_it_in arr lst + = foldr fill_one_in (return ()) lst + where -- **** STRICT **** (but that's OK...) + fill_one_in (i, v) rst + = writeArray arr i v >> rst + zap_with_f :: Ix ix => (elt -> elt2 -> elt) -> MutableArray s ix elt -> [(ix,elt2)] -> ST s () -- zap_with_f: reads an elem out first, then uses "f" on that and the new value diff --git a/ghc/lib/std/PrelBase.lhs b/ghc/lib/std/PrelBase.lhs index a4cbf63..2b90eef 100644 --- a/ghc/lib/std/PrelBase.lhs +++ b/ghc/lib/std/PrelBase.lhs @@ -19,9 +19,6 @@ import {-# SOURCE #-} PrelErr ( error ) import PrelGHC infixr 9 . -infixl 9 !! -infixl 7 * -infixl 6 +, - infixr 5 ++, : infix 4 ==, /=, <, <=, >=, > infixr 3 && @@ -56,15 +53,15 @@ class (Eq a) => Ord a where | x <= y = LT | otherwise = GT - x <= y = compare x y /= GT - x < y = compare x y == LT - x >= y = compare x y /= LT - x > y = compare x y == GT - max x y = case (compare x y) of { LT -> y ; EQ -> x ; GT -> x } - min x y = case (compare x y) of { LT -> x ; EQ -> x ; GT -> y } + x <= y = case compare x y of { GT -> False; other -> True } + x < y = case compare x y of { LT -> True; other -> False } + x >= y = case compare x y of { LT -> False; other -> True } + x > y = case compare x y of { GT -> True; other -> False } -class Bounded a where - minBound, maxBound :: a + -- These two default methods use '>' rather than compare + -- because the latter is often more expensive + max x y = if x > y then x else y + min x y = if x > y then y else x \end{code} %********************************************************* @@ -91,76 +88,6 @@ class Monad m where %********************************************************* %* * -\subsection{Classes @Num@ and @Enum@} -%* * -%********************************************************* - -\begin{code} -class Enum a where - succ, pred :: a -> a - toEnum :: Int -> a - fromEnum :: a -> Int - enumFrom :: a -> [a] -- [n..] - enumFromThen :: a -> a -> [a] -- [n,n'..] - enumFromTo :: a -> a -> [a] -- [n..m] - enumFromThenTo :: a -> a -> a -> [a] -- [n,n'..m] - - succ = toEnum . (+1) . fromEnum - pred = toEnum . (+(-1)) . fromEnum - enumFromTo n m = map toEnum [fromEnum n .. fromEnum m] - enumFromThenTo n n' m - = map toEnum [fromEnum n, fromEnum n' .. fromEnum m] - -class (Eq a, Show a) => Num a where - (+), (-), (*) :: a -> a -> a - negate :: a -> a - abs, signum :: a -> a - fromInteger :: Integer -> a - fromInt :: Int -> a -- partain: Glasgow extension - - x - y = x + negate y - negate x = 0 - x - fromInt (I# i#) = fromInteger (S# i#) - -- Go via the standard class-op if the - -- non-standard one ain't provided -\end{code} - -\begin{code} -chr :: Int -> Char -chr = toEnum -ord :: Char -> Int -ord = fromEnum - -ord_0 :: Num a => a -ord_0 = fromInt (ord '0') - -{-# SPECIALISE subtract :: Int -> Int -> Int #-} -subtract :: (Num a) => a -> a -> a -subtract x y = y - x -\end{code} - - -%********************************************************* -%* * -\subsection{The @Show@ class} -%* * -%********************************************************* - -\begin{code} -type ShowS = String -> String - -class Show a where - showsPrec :: Int -> a -> ShowS - show :: a -> String - showList :: [a] -> ShowS - - showList ls = showList__ (showsPrec 0) ls - showsPrec _ x s = show x ++ s - show x = showsPrec 0 x "" -\end{code} - -%********************************************************* -%* * \subsection{The list type} %* * %********************************************************* @@ -169,8 +96,6 @@ class Show a where data [] a = [] | a : [a] -- do explicitly: deriving (Eq, Ord) -- to avoid weird names like con2tag_[]# - - instance (Eq a) => Eq [a] where [] == [] = True (x:xs) == (y:ys) = x == y && xs == ys @@ -184,9 +109,6 @@ instance (Ord a) => Ord [a] where a >= b = case compare a b of { LT -> False; EQ -> True; GT -> True } a > b = case compare a b of { LT -> False; EQ -> False; GT -> True } - max a b = case compare a b of { LT -> b; EQ -> a; GT -> a } - min a b = case compare a b of { LT -> a; EQ -> a; GT -> b } - compare [] [] = EQ compare (_:_) [] = GT compare [] (_:_) = LT @@ -195,14 +117,6 @@ instance (Ord a) => Ord [a] where GT -> GT EQ -> compare xs ys -map :: (a -> b) -> [a] -> [b] -map _ [] = [] -map f (x:xs) = f x : map f xs - -(++) :: [a] -> [a] -> [a] -[] ++ ys = ys -(x:xs) ++ ys = x : (xs ++ ys) - instance Functor [] where fmap = map @@ -211,59 +125,81 @@ instance Monad [] where m >> k = foldr ((++) . (\ _ -> k)) [] m return x = [x] fail _ = [] +\end{code} + +A few list functions that appear here because they are used here. +The rest of the prelude list functions are in PrelList. -instance (Show a) => Show [a] where - showsPrec _ = showList - showList ls = showList__ (showsPrec 0) ls +---------------------------------------------- +-- foldr/build/augment +---------------------------------------------- + +\begin{code} +foldr :: (a -> b -> b) -> b -> [a] -> b +foldr _ z [] = z +foldr f z (x:xs) = f x (foldr f z xs) + +build :: forall a. (forall b. (a -> b -> b) -> b -> b) -> [a] +{-# INLINE build #-} + -- The INLINE is important, even though build is tiny, + -- because it prevents [] getting inlined in the version that + -- appears in the interface file. If [] *is* inlined, it + -- won't match with [] appearing in rules in an importing module. +build g = g (:) [] + +augment :: forall a. (forall b. (a->b->b) -> b -> b) -> [a] -> [a] +{-# INLINE augment #-} +augment g xs = g (:) xs + +{-# RULES +"fold/build" forall k,z,g::forall b. (a->b->b) -> b -> b . + foldr k z (build g) = g k z + +"foldr/augment" forall k,z,xs,g::forall b. (a->b->b) -> b -> b . + foldr k z (augment g xs) = g k (foldr k z xs) + +"foldr/id" foldr (:) [] = \x->x +"foldr/app" forall xs, ys. foldr (:) ys xs = append xs ys + +"foldr/cons" forall k,z,x,xs. foldr k z (x:xs) = k x (foldr k z xs) +"foldr/nil" forall k,z. foldr k z [] = z + #-} \end{code} + +---------------------------------------------- +-- map +---------------------------------------------- + +\begin{code} +map :: (a -> b) -> [a] -> [b] +{-# INLINE map #-} +map f xs = build (\c n -> foldr (mapFB c f) n xs) + +mapFB c f xs = c (f xs) + +mapList :: (a -> b) -> [a] -> [b] +mapList _ [] = [] +mapList f (x:xs) = f x : mapList f xs + +{-# RULES +"mapFB" forall c,f,g. mapFB (mapFB c f) g = mapFB c (f.g) +"mapList" forall f. foldr (mapFB (:) f) [] = mapList f + #-} \end{code} -A few list functions that appear here because they are used here. -The rest of the prelude list functions are in PrelList. +---------------------------------------------- +-- append +---------------------------------------------- \begin{code} -foldr :: (a -> b -> b) -> b -> [a] -> b -foldr _ z [] = z -foldr f z (x:xs) = f x (foldr f z xs) - --- takeWhile, applied to a predicate p and a list xs, returns the longest --- prefix (possibly empty) of xs of elements that satisfy p. dropWhile p xs --- returns the remaining suffix. Span p xs is equivalent to --- (takeWhile p xs, dropWhile p xs), while break p uses the negation of p. - -takeWhile :: (a -> Bool) -> [a] -> [a] -takeWhile _ [] = [] -takeWhile p (x:xs) - | p x = x : takeWhile p xs - | otherwise = [] - -dropWhile :: (a -> Bool) -> [a] -> [a] -dropWhile _ [] = [] -dropWhile p xs@(x:xs') - | p x = dropWhile p xs' - | otherwise = xs - --- List index (subscript) operator, 0-origin -(!!) :: [a] -> Int -> a -#ifdef USE_REPORT_PRELUDE -(x:_) !! 0 = x -(_:xs) !! n | n > 0 = xs !! (n-1) -(_:_) !! _ = error "Prelude.(!!): negative index" -[] !! _ = error "Prelude.(!!): index too large" -#else --- HBC version (stolen), then unboxified --- The semantics is not quite the same for error conditions --- in the more efficient version. --- -_ !! n | n < 0 = error "Prelude.(!!): negative index\n" -xs !! n = sub xs (case n of { I# n# -> n# }) - where sub :: [a] -> Int# -> a - sub [] _ = error "Prelude.(!!): index too large\n" - sub (y:ys) n# = if n# ==# 0# - then y - else sub ys (n# -# 1#) -#endif +(++) :: [a] -> [a] -> [a] +{-# INLINE (++) #-} +xs ++ ys = augment (\c n -> foldr c n xs) ys + +append :: [a] -> [a] -> [a] +append [] ys = ys +append (x:xs) ys = x : append xs ys \end{code} @@ -274,7 +210,8 @@ xs !! n = sub xs (case n of { I# n# -> n# }) %********************************************************* \begin{code} -data Bool = False | True deriving (Eq, Ord, Enum, Bounded, Show {- Read -}) +data Bool = False | True deriving (Eq, Ord) + -- Read in PrelRead, Show in PrelShow -- Boolean functions @@ -307,8 +244,7 @@ need (). (We could arrange suck in () only if -fglasgow-exts, but putting it here seems more direct. \begin{code} -data () = () --easier to do explicitly: deriving (Eq, Ord, Enum, Show, Bounded) - -- (avoids weird-named functions, e.g., con2tag_()# +data () = () instance Eq () where () == () = True @@ -322,23 +258,9 @@ instance Ord () where max () () = () min () () = () compare () () = EQ - -instance Enum () where - succ x = error "Prelude.Enum.succ{()}: not possible" - pred x = error "Prelude.Enum.pred{()}: not possible" - toEnum 0 = () - toEnum _ = error "Prelude.Enum.toEnum{()}: argument not 0" - fromEnum () = 0 - enumFrom () = [()] - enumFromThen () () = [()] - enumFromTo () () = [()] - enumFromThenTo () () () = [()] - -instance Show () where - showsPrec _ () = showString "()" - showList ls = showList__ (showsPrec 0) ls \end{code} + %********************************************************* %* * \subsection{Type @Ordering@} @@ -346,7 +268,8 @@ instance Show () where %********************************************************* \begin{code} -data Ordering = LT | EQ | GT deriving (Eq, Ord, Enum, Bounded, Show {- in PrelRead: Read -}) +data Ordering = LT | EQ | GT deriving (Eq, Ord) + -- Read in PrelRead, Show in PrelShow \end{code} @@ -361,118 +284,18 @@ type String = [Char] data Char = C# Char# deriving (Eq, Ord) -instance Enum Char where - succ c@(C# c#) - | not (ord# c# ==# 255#) = C# (chr# (ord# c# +# 1#)) - | otherwise = error ("Prelude.Enum.succ{Char}: tried to take `succ' of maxBound") - pred c@(C# c#) - | not (ord# c# ==# 0#) = C# (chr# (ord# c# -# 1#)) - | otherwise = error ("Prelude.Enum.pred{Char}: tried to to take `pred' of minBound") - - toEnum (I# i) | i >=# 0# && i <=# 255# = C# (chr# i) - | otherwise = error ("Prelude.Enum.toEnum{Char}: out of range: " ++ show (I# i)) - fromEnum (C# c) = I# (ord# c) - - enumFrom (C# c) = efttCh (ord# c) 1# (># 255#) - enumFromTo (C# c1) (C# c2) - | c1 `leChar#` c2 = efttCh (ord# c1) 1# (># (ord# c2)) - | otherwise = [] - - enumFromThen (C# c1) (C# c2) - | c1 `leChar#` c2 = efttCh (ord# c1) (ord# c2 -# ord# c1) (># 255#) - | otherwise = efttCh (ord# c1) (ord# c2 -# ord# c1) (<# 0#) - - enumFromThenTo (C# c1) (C# c2) (C# c3) - | c1 `leChar#` c2 = efttCh (ord# c1) (ord# c2 -# ord# c1) (># (ord# c3)) - | otherwise = efttCh (ord# c1) (ord# c2 -# ord# c1) (<# (ord# c3)) - -efttCh :: Int# -> Int# -> (Int# -> Bool) -> [Char] -efttCh init step done - = go init - where - go now | done now = [] - | otherwise = C# (chr# now) : go (now +# step) - -instance Show Char where - showsPrec _ '\'' = showString "'\\''" - showsPrec _ c = showChar '\'' . showLitChar c . showChar '\'' - - showList cs = showChar '"' . showl cs - where showl "" = showChar '"' - showl ('"':xs) = showString "\\\"" . showl xs - showl (x:xs) = showLitChar x . showl xs -\end{code} +chr :: Int -> Char +chr (I# i) | i >=# 0# && i <=# 255# = C# (chr# i) + | otherwise = error ("Prelude.chr: bad argument") +unsafeChr :: Int -> Char +unsafeChr (I# i) = C# (chr# i) -\begin{code} -isAscii, isLatin1, isControl, isPrint, isSpace, isUpper, - isLower, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum :: 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 PrelList 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' - = toEnum (fromEnum c - fromEnum 'a' + fromEnum 'A') - | otherwise - = c - - - -toLower c@(C# c#) - | isAsciiUpper c = C# (chr# (ord# c# +# 32#)) - | isAscii c = c - | isUpper c = toEnum (fromEnum c - fromEnum 'A' - + fromEnum '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"] +ord :: Char -> Int +ord (C# c) = I# (ord# c) \end{code} + %********************************************************* %* * \subsection{Type @Int@} @@ -482,6 +305,13 @@ asciiTab = -- Using an array drags in the array module. listArray ('\NUL', ' ') \begin{code} data Int = I# Int# +zeroInt, oneInt, twoInt, maxInt, minInt :: Int +zeroInt = I# 0# +oneInt = I# 1# +twoInt = I# 2# +maxInt = I# (-2147483648#) -- GHC <= 2.09 had this at -2147483647 +minInt = I# 2147483647# + instance Eq Int where (==) x y = x `eqInt` y (/=) x y = x `neInt` y @@ -493,84 +323,11 @@ instance Ord Int where (<=) x y = leInt x y (>=) x y = geInt x y (>) x y = gtInt x y - max x y = case (compareInt x y) of { LT -> y ; EQ -> x ; GT -> x } - min x y = case (compareInt x y) of { LT -> x ; EQ -> x ; GT -> y } compareInt :: Int -> Int -> Ordering (I# x) `compareInt` (I# y) | x <# y = LT | x ==# y = EQ | otherwise = GT - -instance Bounded Int where - minBound = -2147483648 -- GHC <= 2.09 had this at -2147483647 - maxBound = 2147483647 - -instance Enum Int where - succ x - | x == maxBound = error "Prelude.Enum.succ{Int}: tried to take `succ' of maxBound" - | otherwise = x+1 - pred x - | x == minBound = error "Prelude.Enum.pred{Int}: tried to take `pred' of minBound" - | otherwise = x-1 - - toEnum x = x - fromEnum x = x - -#ifndef USE_FOLDR_BUILD - enumFrom (I# c) = efttInt True c 1# (\ _ -> False) - - enumFromTo (I# c1) (I# c2) - | c1 <=# c2 = efttInt True c1 1# (># c2) - | otherwise = [] - - enumFromThen (I# c1) (I# c2) - | c1 <# c2 = efttInt True c1 (c2 -# c1) (\ _ -> False) - | otherwise = efttInt False c1 (c2 -# c1) (\ _ -> False) - - enumFromThenTo (I# c1) (I# c2) (I# c3) - | c1 <=# c2 = efttInt True c1 (c2 -# c1) (># c3) - | otherwise = efttInt False c1 (c2 -# c1) (<# c3) - -#else - {-# INLINE enumFrom #-} - {-# INLINE enumFromTo #-} - enumFrom x = build (\ c _ -> - let g x = x `c` g (x `plusInt` 1) in g x) - enumFromTo x y = build (\ c n -> - let g x = if x <= y then x `c` g (x `plusInt` 1) else n in g x) -#endif - -efttInt :: Bool -> Int# -> Int# -> (Int# -> Bool) -> [Int] -efttInt increasing init step done = go init - where - go now - | done now = [] - | increasing && now ># nxt = [I# now] -- overflowed - | not increasing && now <# nxt = [I# now] -- underflowed - | otherwise = I# now : go nxt - where - nxt = now +# step - -instance Num Int where - (+) x y = plusInt x y - (-) x y = minusInt x y - negate x = negateInt x - (*) x y = timesInt x y - abs n = if n `geInt` 0 then n else (negateInt n) - - signum n | n `ltInt` 0 = negateInt 1 - | n `eqInt` 0 = 0 - | otherwise = 1 - - fromInteger (S# i#) = I# i# - fromInteger (J# s# d#) - = case (integer2Int# s# d#) of { i# -> I# i# } - - fromInt n = n - -instance Show Int where - showsPrec p n = showSignedInt p n - showList ls = showList__ (showsPrec 0) ls \end{code} @@ -600,6 +357,7 @@ instance Eq Integer where (J# s1 d1) /= (J# s2 d2) = (cmpInteger# s1 d1 s2 d2) /=# 0# \end{code} + %********************************************************* %* * \subsection{The function type} @@ -643,90 +401,6 @@ asTypeOf = const %********************************************************* %* * -\subsection{Support code for @Show@} -%* * -%********************************************************* - -\begin{code} -shows :: (Show a) => a -> ShowS -shows = showsPrec 0 - -showChar :: Char -> ShowS -showChar = (:) - -showString :: String -> ShowS -showString = (++) - -showParen :: Bool -> ShowS -> ShowS -showParen b p = if b then showChar '(' . p . showChar ')' else p - -showList__ :: (a -> ShowS) -> [a] -> ShowS - -showList__ _ [] = showString "[]" -showList__ showx (x:xs) = showChar '[' . showx x . showl xs - where - showl [] = showChar ']' - showl (y:ys) = showChar ',' . showx y . showl ys - -showSpace :: ShowS -showSpace = {-showChar ' '-} \ xs -> ' ' : xs -\end{code} - -Code specific for characters - -\begin{code} -showLitChar :: Char -> ShowS -showLitChar c | c > '\DEL' = showChar '\\' . protectEsc isDigit (shows (ord c)) -showLitChar '\DEL' = showString "\\DEL" -showLitChar '\\' = showString "\\\\" -showLitChar c | c >= ' ' = showChar c -showLitChar '\a' = showString "\\a" -showLitChar '\b' = showString "\\b" -showLitChar '\f' = showString "\\f" -showLitChar '\n' = showString "\\n" -showLitChar '\r' = showString "\\r" -showLitChar '\t' = showString "\\t" -showLitChar '\v' = showString "\\v" -showLitChar '\SO' = protectEsc (== 'H') (showString "\\SO") -showLitChar c = showString ('\\' : asciiTab!!ord c) - -protectEsc :: (Char -> Bool) -> ShowS -> ShowS -protectEsc p f = f . cont - where cont s@(c:_) | p c = "\\&" ++ s - cont s = s - -intToDigit :: Int -> Char -intToDigit i - | i >= 0 && i <= 9 = toEnum (fromEnum '0' + i) - | i >= 10 && i <= 15 = toEnum (fromEnum 'a' + i - 10) - | otherwise = error ("Char.intToDigit: not a digit " ++ show i) - -\end{code} - -Code specific for Ints. - -\begin{code} -showSignedInt :: Int -> Int -> ShowS -showSignedInt p (I# n) r - | n <# 0# && p > 6 = '(':itos n (')':r) - | otherwise = itos n r - -itos :: Int# -> String -> String -itos n r - | n >=# 0# = itos' n r - | negateInt# n <# 0# = -- n is minInt, a difficult number - itos (n `quotInt#` 10#) (itos' (negateInt# (n `remInt#` 10#)) r) - | otherwise = '-':itos' (negateInt# n) r - where - itos' :: Int# -> String -> String - itos' x cs - | x <# 10# = C# (chr# (x +# ord# '0'#)) : cs - | otherwise = itos' (x `quotInt#` 10#) - (C# (chr# (x `remInt#` 10# +# ord# '0'#)) : cs) -\end{code} - -%********************************************************* -%* * \subsection{Numeric primops} %* * %********************************************************* @@ -737,6 +411,16 @@ used in the case of partial applications, etc. \begin{code} {-# INLINE eqInt #-} {-# INLINE neInt #-} +{-# INLINE gtInt #-} +{-# INLINE geInt #-} +{-# INLINE ltInt #-} +{-# INLINE leInt #-} +{-# INLINE plusInt #-} +{-# INLINE minusInt #-} +{-# INLINE timesInt #-} +{-# INLINE quotInt #-} +{-# INLINE remInt #-} +{-# INLINE negateInt #-} plusInt, minusInt, timesInt, quotInt, remInt :: Int -> Int -> Int plusInt (I# x) (I# y) = I# (x +# y) diff --git a/ghc/lib/std/PrelBounded.lhs b/ghc/lib/std/PrelBounded.lhs deleted file mode 100644 index de8699e..0000000 --- a/ghc/lib/std/PrelBounded.lhs +++ /dev/null @@ -1,23 +0,0 @@ -% -% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996 -% -\section[PrelBounded]{Module @PrelBounded@} - -Instances of Bounded for various datatypes. - -\begin{code} -{-# OPTIONS -fno-implicit-prelude #-} - -module PrelBounded where - -import PrelBase - -instance Bounded () where - minBound = () - maxBound = () - -instance Bounded Char where - minBound = '\0' - maxBound = '\255' - -\end{code} diff --git a/ghc/lib/std/PrelConc.lhs b/ghc/lib/std/PrelConc.lhs index c23e8d8..06265f5 100644 --- a/ghc/lib/std/PrelConc.lhs +++ b/ghc/lib/std/PrelConc.lhs @@ -56,7 +56,7 @@ data ThreadId = ThreadId ThreadId# -- But since ThreadId# is unlifted, the Weak type must use open -- type variables. ---forkIO has now been hoisted out into the concurrent library. +--forkIO has now been hoisted out into the Concurrent library. killThread :: ThreadId -> IO () killThread (ThreadId id) = IO $ \ s -> @@ -97,7 +97,6 @@ par x y = case (par# x) of { 0# -> parError; _ -> y } #else par _ y = y #endif - \end{code} %************************************************************************ diff --git a/ghc/lib/std/PrelEither.lhs b/ghc/lib/std/PrelEither.lhs deleted file mode 100644 index ada0a96..0000000 --- a/ghc/lib/std/PrelEither.lhs +++ /dev/null @@ -1,20 +0,0 @@ -% -% (c) The GRASP/AQUA Project, Glasgow University, 1992-1997 -% -\section[PrelEither]{Module @PrelEither@} - -The @Either@ Type. - -\begin{code} -{-# OPTIONS -fno-implicit-prelude #-} - -module PrelEither where - -import PrelBase - -data Either a b = Left a | Right b deriving (Eq, Ord, Show {- Read -} ) - -either :: (a -> c) -> (b -> c) -> Either a b -> c -either f _ (Left x) = f x -either _ g (Right y) = g y -\end{code} diff --git a/ghc/lib/std/PrelEnum.lhs b/ghc/lib/std/PrelEnum.lhs new file mode 100644 index 0000000..4651f0c --- /dev/null +++ b/ghc/lib/std/PrelEnum.lhs @@ -0,0 +1,317 @@ +% +% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996 +% +\section[PrelBounded]{Module @PrelBounded@} + +Instances of Bounded for various datatypes. + +\begin{code} +{-# OPTIONS -fno-implicit-prelude #-} + +module PrelEnum( + Bounded(..), Enum(..), + enumFromBounded, enumFromThenBounded, + + -- Instances for Bounded and Eum: (), Char, Int + + ) where + +import {-# SOURCE #-} PrelErr ( error ) +import PrelBase +import PrelTup () -- To make sure we look for the .hi file +\end{code} + + +%********************************************************* +%* * +\subsection{Class declarations} +%* * +%********************************************************* + +\begin{code} +class Bounded a where + minBound, maxBound :: a + +class Enum a where + succ, pred :: a -> a + toEnum :: Int -> a + fromEnum :: a -> Int + enumFrom :: a -> [a] -- [n..] + enumFromThen :: a -> a -> [a] -- [n,n'..] + enumFromTo :: a -> a -> [a] -- [n..m] + enumFromThenTo :: a -> a -> a -> [a] -- [n,n'..m] + + succ = toEnum . (`plusInt` oneInt) . fromEnum + pred = toEnum . (`minusInt` oneInt) . fromEnum + enumFromTo n m = map toEnum [fromEnum n .. fromEnum m] + enumFromThenTo n1 n2 m = map toEnum [fromEnum n1, fromEnum n2 .. fromEnum m] + +-- Default methods for bounded enumerations +enumFromBounded :: (Enum a, Bounded a) => a -> [a] +enumFromBounded n = enumFromTo n maxBound + +enumFromThenBounded :: (Enum a, Bounded a) => a -> a -> [a] +enumFromThenBounded n1 n2 = enumFromThenTo n1 n2 maxBound +\end{code} + + +%********************************************************* +%* * +\subsection{Tuples} +%* * +%********************************************************* + +\begin{code} +instance Bounded () where + minBound = () + maxBound = () + +instance Enum () where + succ x = error "Prelude.Enum.().succ: bad argment" + pred x = error "Prelude.Enum.().pred: bad argument" + + toEnum x | x == zeroInt = () + | otherwise = error "Prelude.Enum.().toEnum: bad argument" + + fromEnum () = zeroInt + enumFrom () = [()] + enumFromThen () () = [()] + enumFromTo () () = [()] + enumFromThenTo () () () = [()] +\end{code} + +\begin{code} +instance (Bounded a, Bounded b) => Bounded (a,b) where + minBound = (minBound, minBound) + maxBound = (maxBound, maxBound) + +instance (Bounded a, Bounded b, Bounded c) => Bounded (a,b,c) where + minBound = (minBound, minBound, minBound) + maxBound = (maxBound, maxBound, maxBound) + +instance (Bounded a, Bounded b, Bounded c, Bounded d) => Bounded (a,b,c,d) where + minBound = (minBound, minBound, minBound, minBound) + maxBound = (maxBound, maxBound, maxBound, maxBound) +\end{code} + + +%********************************************************* +%* * +\subsection{Type @Bool@} +%* * +%********************************************************* + +\begin{code} +instance Bounded Bool where + minBound = False + maxBound = True + +instance Enum Bool where + succ False = True + succ True = error "Prelude.Enum.Bool.succ: bad argment" + + pred True = False + pred False = error "Prelude.Enum.Bool.pred: bad argment" + + toEnum n | n == zeroInt = False + | n == oneInt = True + | otherwise = error "Prelude.Enum.Bool.toEnum: bad argment" + + fromEnum False = zeroInt + fromEnum True = oneInt + + -- Use defaults for the rest + enumFrom = enumFromBounded + enumFromThen = enumFromThenBounded +\end{code} + +%********************************************************* +%* * +\subsection{Type @Ordering@} +%* * +%********************************************************* + +\begin{code} +instance Bounded Ordering where + minBound = LT + maxBound = GT + +instance Enum Ordering where + succ LT = EQ + succ EQ = GT + succ GT = error "Prelude.Enum.Ordering.succ: bad argment" + + pred GT = EQ + pred EQ = LT + pred LT = error "Prelude.Enum.Ordering.pred: bad argment" + + toEnum n | n == zeroInt = LT + | n == oneInt = EQ + | n == twoInt = GT + toEnum n = error "Prelude.Enum.Ordering.toEnum: bad argment" + + fromEnum LT = zeroInt + fromEnum EQ = oneInt + fromEnum GT = twoInt + + -- Use defaults for the rest + enumFrom = enumFromBounded + enumFromThen = enumFromThenBounded +\end{code} + +%********************************************************* +%* * +\subsection{Type @Char@} +%* * +%********************************************************* + +\begin{code} +instance Bounded Char where + minBound = '\0' + maxBound = '\255' + +instance Enum Char where + succ c@(C# c#) + | not (ord# c# ==# 255#) = C# (chr# (ord# c# +# 1#)) + | otherwise = error ("Prelude.Enum.Char.succ: bad argument") + pred c@(C# c#) + | not (ord# c# ==# 0#) = C# (chr# (ord# c# -# 1#)) + | otherwise = error ("Prelude.Enum.Char.pred: bad argument") + + toEnum = chr + fromEnum = ord + + {-# INLINE enumFrom #-} + enumFrom (C# x) = build (\ c n -> eftCharFB c n (ord# x) 255#) + -- Blarg: technically I guess enumFrom isn't strict! + + {-# INLINE enumFromTo #-} + enumFromTo (C# x) (C# y) = build (\ c n -> eftCharFB c n (ord# x) (ord# y)) + + {-# INLINE enumFromThen #-} + enumFromThen (C# x1) (C# x2) = build (\ c n -> efdtCharFB c n (ord# x1) (ord# x2) 255#) + + {-# INLINE enumFromThenTo #-} + enumFromThenTo (C# x1) (C# x2) (C# y) = build (\ c n -> efdtCharFB c n (ord# x1) (ord# x2) (ord# y)) + +-- We can do better than for Ints because we don't +-- have hassles about arithmetic overflow at maxBound +{-# INLINE eftCharFB #-} +eftCharFB c n x y = go x + where + go x | x ># y = n + | otherwise = C# (chr# x) `c` go (x +# 1#) + +eftCharList x y | x ># y = [] + | otherwise = C# (chr# x) : eftCharList (x +# 1#) y + + +-- For enumFromThenTo we give up on inlining +efdtCharFB c n x1 x2 y + | delta >=# 0# = go_up x1 + | otherwise = go_dn x1 + where + delta = x2 -# x1 + go_up x | x ># y = n + | otherwise = C# (chr# x) `c` go_up (x +# delta) + go_dn x | x <# y = n + | otherwise = C# (chr# x) `c` go_dn (x +# delta) + +efdtCharList x1 x2 y + | delta >=# 0# = go_up x1 + | otherwise = go_dn x1 + where + delta = x2 -# x1 + go_up x | x ># y = [] + | otherwise = C# (chr# x) : go_up (x +# delta) + go_dn x | x <# y = [] + | otherwise = C# (chr# x) : go_dn (x +# delta) + + +{-# RULES +"eftCharList" eftCharFB (:) [] = eftCharList +"efdtCharList" efdtCharFB (:) [] = efdtCharList + #-} +\end{code} + + +%********************************************************* +%* * +\subsection{Type @Int@} +%* * +%********************************************************* + +\begin{code} +instance Bounded Int where + minBound = minInt + maxBound = maxInt + +instance Enum Int where + succ x + | x == maxBound = error "Prelude.Enum.succ{Int}: tried to take `succ' of maxBound" + | otherwise = x `plusInt` oneInt + pred x + | x == minBound = error "Prelude.Enum.pred{Int}: tried to take `pred' of minBound" + | otherwise = x `minusInt` oneInt + + toEnum x = x + fromEnum x = x + + {-# INLINE enumFrom #-} + enumFrom (I# x) = build (\ c n -> eftIntFB c n x 2147483647#) + -- Blarg: technically I guess enumFrom isn't strict! + + {-# INLINE enumFromTo #-} + enumFromTo (I# x) (I# y) = build (\ c n -> eftIntFB c n x y) + + {-# INLINE enumFromThen #-} + enumFromThen (I# x1) (I# x2) = build (\ c n -> efdtIntFB c n x1 x2 2147483647#) + + {-# INLINE enumFromThenTo #-} + enumFromThenTo (I# x1) (I# x2) (I# y) = build (\ c n -> efdtIntFB c n x1 x2 y) + +{-# INLINE eftIntFB #-} +eftIntFB c n x y | x ># y = n + | otherwise = go x + where + go x = I# x `c` if x ==# y then n else go (x +# 1#) + -- Watch out for y=maxBound; hence ==, not > + -- Be very careful not to have more than one "c" + -- so that when eftInfFB is inlined we can inline + -- whatver is bound to "c" + +eftIntList x y | x ># y = [] + | otherwise = go x + where + go x = I# x : if x ==# y then [] else go (x +# 1#) + + +-- For enumFromThenTo we give up on inlining; so we don't worry +-- about duplicating occurrences of "c" +efdtIntFB c n x1 x2 y + | delta >=# 0# = if x1 ># y then n else go_up x1 + | otherwise = if x1 <# y then n else go_dn x1 + where + delta = x2 -# x1 + go_up x | y -# x <# delta = I# x `c` n + | otherwise = I# x `c` go_up (x +# delta) + go_dn x | y -# x ># delta = I# x `c` n + | otherwise = I# x `c` go_dn (x +# delta) + +efdtIntList x1 x2 y + | delta >=# 0# = if x1 ># y then [] else go_up x1 + | otherwise = if x1 <# y then [] else go_dn x1 + where + delta = x2 -# x1 + go_up x | y -# x <# delta = [I# x] + | otherwise = I# x : go_up (x +# delta) + go_dn x | y -# x ># delta = [I# x] + | otherwise = I# x : go_dn (x +# delta) + + +{-# RULES +"eftIntList" eftIntFB (:) [] = eftIntList +"efdtIntList" efdtIntFB (:) [] = efdtIntList + #-} +\end{code} + diff --git a/ghc/lib/std/PrelErr.hi-boot b/ghc/lib/std/PrelErr.hi-boot index 7f4b628..bd7f8f9 100644 --- a/ghc/lib/std/PrelErr.hi-boot +++ b/ghc/lib/std/PrelErr.hi-boot @@ -8,5 +8,5 @@ --------------------------------------------------------------------------- __interface PrelErr 2 0 where -__export ! PrelErr error parError; +__export PrelErr error parError; diff --git a/ghc/lib/std/PrelErr.lhs b/ghc/lib/std/PrelErr.lhs index 7c96aac..c0269cd 100644 --- a/ghc/lib/std/PrelErr.lhs +++ b/ghc/lib/std/PrelErr.lhs @@ -34,7 +34,6 @@ module PrelErr import PrelBase import PrelList ( span ) import PrelException - \end{code} %********************************************************* diff --git a/ghc/lib/std/PrelException.hi-boot b/ghc/lib/std/PrelException.hi-boot index 6d0e84f..511010d 100644 --- a/ghc/lib/std/PrelException.hi-boot +++ b/ghc/lib/std/PrelException.hi-boot @@ -6,7 +6,7 @@ --------------------------------------------------------------------------- __interface PrelException 1 0 where -__export ! PrelException ioError catch; +__export PrelException ioError catch; 1 ioError :: __forall [a] => PrelIOBase.IOError -> PrelIOBase.IO a ; 1 catch :: __forall [a] => PrelIOBase.IO a -> (PrelIOBase.IOError -> PrelIOBase.IO a) -> PrelIOBase.IO a ; -- wish there could be more __o's here. KSW 1999-04. diff --git a/ghc/lib/std/PrelException.lhs b/ghc/lib/std/PrelException.lhs index 1658c9d..8fa7228 100644 --- a/ghc/lib/std/PrelException.lhs +++ b/ghc/lib/std/PrelException.lhs @@ -1,5 +1,5 @@ % ----------------------------------------------------------------------------- -% $Id: PrelException.lhs,v 1.6 1999/05/10 16:52:10 sof Exp $ +% $Id: PrelException.lhs,v 1.7 1999/05/18 14:59:16 simonpj Exp $ % % (c) The GRAP/AQUA Project, Glasgow University, 1998 % @@ -13,6 +13,7 @@ Exceptions and exception-handling functions. module PrelException where import PrelBase +import PrelShow import PrelIOBase import PrelST ( STret(..) ) import PrelDynamic @@ -122,6 +123,7 @@ catchNonIO m k = catchException m handler handler other = k other \end{code} + Why is this stuff here? To avoid recursive module dependencies of course. diff --git a/ghc/lib/std/PrelHandle.lhs b/ghc/lib/std/PrelHandle.lhs index 079e144..0e2a393 100644 --- a/ghc/lib/std/PrelHandle.lhs +++ b/ghc/lib/std/PrelHandle.lhs @@ -22,7 +22,10 @@ import PrelList ( span ) import PrelIOBase import PrelException import PrelMaybe ( Maybe(..) ) -import PrelBounded () -- get at Bounded Int instance. +import PrelEnum +import PrelNum +import PrelShow +import PrelAddr ( Addr, nullAddr ) import PrelNum ( toInteger, toBig ) import PrelPack ( packString ) import PrelWeak ( addForeignFinalizer ) diff --git a/ghc/lib/std/PrelIOBase.lhs b/ghc/lib/std/PrelIOBase.lhs index 4aaff45..3f9730f 100644 --- a/ghc/lib/std/PrelIOBase.lhs +++ b/ghc/lib/std/PrelIOBase.lhs @@ -1,5 +1,5 @@ % ----------------------------------------------------------------------------- -% $Id: PrelIOBase.lhs,v 1.9 1999/04/27 17:41:19 sof Exp $ +% $Id: PrelIOBase.lhs,v 1.10 1999/05/18 14:59:18 simonpj Exp $ % % (c) The AQUA Project, Glasgow University, 1994-1998 % @@ -25,6 +25,7 @@ import PrelST ( ST(..), STret(..) ) import PrelMaybe ( Maybe(..) ) import PrelAddr ( Addr(..), nullAddr ) import PrelPack ( unpackCString ) +import PrelShow #if !defined(__CONCURRENT_HASKELL__) import PrelArr ( MutableVar, readVar ) diff --git a/ghc/lib/std/PrelList.lhs b/ghc/lib/std/PrelList.lhs index 5e99d90..d6514e3 100644 --- a/ghc/lib/std/PrelList.lhs +++ b/ghc/lib/std/PrelList.lhs @@ -17,9 +17,9 @@ module PrelList ( foldl, foldl1, scanl, scanl1, foldr, foldr1, scanr, scanr1, iterate, repeat, replicate, cycle, take, drop, splitAt, takeWhile, dropWhile, span, break, - lines, words, unlines, unwords, reverse, and, or, + reverse, and, or, any, all, elem, notElem, lookup, - sum, product, maximum, minimum, concatMap, + maximum, minimum, concatMap, zip, zip3, zipWith, zipWith3, unzip, unzip3, -- non-standard, but hidden when creating the Prelude @@ -33,6 +33,7 @@ import PrelTup import PrelMaybe import PrelBase +infixl 9 !! infix 4 `elem`, `notElem` \end{code} @@ -90,26 +91,32 @@ null (_:_) = False -- of the more general genericLength, the result type of which may be -- any kind of number. length :: [a] -> Int -#ifdef USE_REPORT_PRELUDE -length [] = 0 -length (_:l) = 1 + length l -#else length l = len l 0# where len :: [a] -> Int# -> Int len [] a# = I# a# len (_:xs) a# = len xs (a# +# 1#) -#endif -- filter, applied to a predicate and a list, returns the list of those -- elements that satisfy the predicate; i.e., -- filter p xs = [ x | x <- xs, p x] filter :: (a -> Bool) -> [a] -> [a] -filter _pred [] = [] -filter pred (x:xs) - | pred x = x : filter pred xs - | otherwise = filter pred xs +{-# INLINE filter #-} +filter p xs = build (\c n -> foldr (filterFB c p) n xs) + +filterFB c p x r | p x = x `c` r + | otherwise = r +{-# RULES +"filterFB" forall c,p,q. filterFB (filterFB c p) q = filterFB c (\x -> p x && q x) +"filterList" forall p. foldr (filterFB (:) p) [] = filterList p + #-} + +filterList :: (a -> Bool) -> [a] -> [a] +filterList _pred [] = [] +filterList pred (x:xs) + | pred x = x : filterList pred xs + | otherwise = filterList pred xs -- foldl, applied to a binary operator, a starting value (typically the -- left-identity of the operator), and a list, reduces the list using @@ -180,6 +187,23 @@ cycle :: [a] -> [a] cycle [] = error "Prelude.cycle: empty list" cycle xs = xs' where xs' = xs ++ xs' +-- takeWhile, applied to a predicate p and a list xs, returns the longest +-- prefix (possibly empty) of xs of elements that satisfy p. dropWhile p xs +-- returns the remaining suffix. Span p xs is equivalent to +-- (takeWhile p xs, dropWhile p xs), while break p uses the negation of p. + +takeWhile :: (a -> Bool) -> [a] -> [a] +takeWhile _ [] = [] +takeWhile p (x:xs) + | p x = x : takeWhile p xs + | otherwise = [] + +dropWhile :: (a -> Bool) -> [a] -> [a] +dropWhile _ [] = [] +dropWhile p xs@(x:xs') + | p x = dropWhile p xs' + | otherwise = xs + -- take n, applied to a list xs, returns the prefix of xs of length n, -- or xs itself if n > length xs. drop n xs returns the suffix of xs -- after the first n elements, or [] if n > length xs. splitAt n xs @@ -197,6 +221,7 @@ drop _ [] = [] drop n (_:xs) | n > 0 = drop (n-1) xs drop _ _ = errorNegativeIdx "drop" + splitAt :: Int -> [a] -> ([a],[a]) splitAt 0 xs = ([],xs) splitAt _ [] = ([],[]) @@ -299,6 +324,13 @@ and [] = True and (x:xs) = x && and xs or [] = False or (x:xs) = x || or xs + +{-# RULES +"and/build" forall g::forall b.(Bool->b->b)->b->b . + and (build g) = g (&&) True +"or/build" forall g::forall b.(Bool->b->b)->b->b . + or (build g) = g (||) False + #-} #endif -- Applied to a predicate and a list, any determines if any element @@ -313,6 +345,12 @@ any p (x:xs) = p x || any p xs all _ [] = True all p (x:xs) = p x && all p xs +{-# RULES +"any/build" forall p, g::forall b.(a->b->b)->b->b . + any p (build g) = g ((&&) . p) True +"all/build" forall p, g::forall b.(a->b->b)->b->b . + all p (build g) = g ((||) . p) False + #-} #endif -- elem is the list membership predicate, usually written in infix form, @@ -336,23 +374,6 @@ lookup key ((x,y):xys) | key == x = Just y | otherwise = lookup key xys --- sum and product compute the sum or product of a finite list of numbers. -{-# SPECIALISE sum :: [Int] -> Int #-} -{-# SPECIALISE product :: [Int] -> Int #-} -sum, product :: (Num a) => [a] -> a -#ifdef USE_REPORT_PRELUDE -sum = foldl (+) 0 -product = foldl (*) 1 -#else -sum l = sum' l 0 - where - sum' [] a = a - sum' (x:xs) a = sum' xs (a+x) -product l = prod l 1 - where - prod [] a = a - prod (x:xs) a = prod xs (a*x) -#endif -- maximum and minimum return the maximum or minimum value from a list, -- which must be non-empty, finite, and of an ordered type. @@ -369,9 +390,33 @@ concatMap :: (a -> [b]) -> [a] -> [b] concatMap f = foldr ((++) . f) [] concat :: [[a]] -> [a] -concat [] = [] -concat ([]:xss) = concat xss -concat ((y:ys):xss) = y: (ys ++ concat xss) +{-# INLINE concat #-} +concat = foldr (++) [] +\end{code} + + +\begin{code} +-- List index (subscript) operator, 0-origin +(!!) :: [a] -> Int -> a +#ifdef USE_REPORT_PRELUDE +(x:_) !! 0 = x +(_:xs) !! n | n > 0 = xs !! (n-1) +(_:_) !! _ = error "Prelude.(!!): negative index" +[] !! _ = error "Prelude.(!!): index too large" +#else +-- HBC version (stolen), then unboxified +-- The semantics is not quite the same for error conditions +-- in the more efficient version. +-- +xs !! (I# n) | n <# 0# = error "Prelude.(!!): negative index\n" + | otherwise = sub xs n + where + sub :: [a] -> Int# -> a + sub [] _ = error "Prelude.(!!): index too large\n" + sub (y:ys) n = if n ==# 0# + then y + else sub ys (n -# 1#) +#endif \end{code} @@ -381,101 +426,106 @@ concat ((y:ys):xss) = y: (ys ++ concat xss) %* * %********************************************************* +\begin{code} +foldr2 k z [] ys = z +foldr2 k z xs [] = z +foldr2 k z (x:xs) (y:ys) = k x y (foldr2 k z xs ys) + +foldr2_left k z x r [] = z +foldr2_left k z x r (y:ys) = k x y (r ys) + +foldr2_right k z y r [] = z +foldr2_right k z y r (x:xs) = k x y (r xs) + +-- foldr2 k z xs ys = foldr (foldr2_left k z) z xs ys +-- foldr2 k z xs ys = foldr (foldr2_right k z) z ys xs +{-# RULES +"foldr2/left" forall k,z,ys,g::forall b.(a->b->b)->b->b . + foldr2 k z (build g) ys = g (foldr2_left k z) (\_ -> z) ys + +"foldr2/right" forall k,z,xs,g::forall b.(a->b->b)->b->b . + foldr2 k z xs (build g) = g (foldr2_right k z) (\_ -> z) xs + #-} +\end{code} + zip takes two lists and returns a list of corresponding pairs. If one input list is short, excess elements of the longer list are discarded. zip3 takes three lists and returns a list of triples. Zips for larger tuples are in the List library \begin{code} -zip :: [a] -> [b] -> [(a,b)] --- Specification --- zip = zipWith (,) -zip (a:as) (b:bs) = (a,b) : zip as bs -zip _ _ = [] +---------------------------------------------- +zip :: [a] -> [b] -> [(a,b)] +{-# INLINE zip #-} +zip xs ys = build (\c n -> foldr2 (zipFB c) n xs ys) + +zipFB c x y r = (x,y) `c` r -zip3 :: [a] -> [b] -> [c] -> [(a,b,c)] + +zipList :: [a] -> [b] -> [(a,b)] +zipList (a:as) (b:bs) = (a,b) : zipList as bs +zipList _ _ = [] + +{-# RULES +"zipList" foldr2 (zipFB (:)) [] = zipList + #-} +\end{code} + +\begin{code} +---------------------------------------------- +zip3 :: [a] -> [b] -> [c] -> [(a,b,c)] -- Specification -- zip3 = zipWith3 (,,) zip3 (a:as) (b:bs) (c:cs) = (a,b,c) : zip3 as bs cs zip3 _ _ _ = [] +\end{code} + -- The zipWith family generalises the zip family by zipping with the -- function given as the first argument, instead of a tupling function. -- For example, zipWith (+) is applied to two lists to produce the list -- of corresponding sums. -zipWith :: (a->b->c) -> [a]->[b]->[c] -zipWith z (a:as) (b:bs) = z a b : zipWith z as bs -zipWith _ _ _ = [] +\begin{code} +---------------------------------------------- +zipWith :: (a->b->c) -> [a]->[b]->[c] +{-# INLINE zipWith #-} +zipWith f xs ys = build (\c n -> foldr2 (zipWithFB c f) n xs ys) + +zipWithFB c f x y r = (x `f` y) `c` r + +zipWithList :: (a->b->c) -> [a] -> [b] -> [c] +zipWithList f (a:as) (b:bs) = f a b : zipWithList f as bs +zipWithList f _ _ = [] + +{-# RULES +"zipWithList" forall f. foldr2 (zipWithFB (:) f) [] = zipWithList f + #-} +\end{code} + +\begin{code} zipWith3 :: (a->b->c->d) -> [a]->[b]->[c]->[d] zipWith3 z (a:as) (b:bs) (c:cs) = z a b c : zipWith3 z as bs cs zipWith3 _ _ _ _ = [] - -- unzip transforms a list of pairs into a pair of lists. +unzip :: [(a,b)] -> ([a],[b]) +unzip = foldr (\(a,b) ~(as,bs) -> (a:as,b:bs)) ([],[]) -unzip :: [(a,b)] -> ([a],[b]) -unzip = foldr (\(a,b) ~(as,bs) -> (a:as,b:bs)) ([],[]) - -unzip3 :: [(a,b,c)] -> ([a],[b],[c]) -unzip3 = foldr (\(a,b,c) ~(as,bs,cs) -> (a:as,b:bs,c:cs)) - ([],[],[]) +unzip3 :: [(a,b,c)] -> ([a],[b],[c]) +unzip3 = foldr (\(a,b,c) ~(as,bs,cs) -> (a:as,b:bs,c:cs)) + ([],[],[]) \end{code} + %********************************************************* %* * -\subsection{Functions on strings} +\subsection{Error code} %* * %********************************************************* -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} - Common up near identical calls to `error' to reduce the number constant strings created when compiled: diff --git a/ghc/lib/std/PrelMain.lhs b/ghc/lib/std/PrelMain.lhs index 9f176fd..3307bb7 100644 --- a/ghc/lib/std/PrelMain.lhs +++ b/ghc/lib/std/PrelMain.lhs @@ -21,4 +21,3 @@ mainIO :: IO () -- It must be of type (IO t) because that's what -- make sure this type signature stays! mainIO = catchException Main.main (topHandler True) \end{code} - diff --git a/ghc/lib/std/PrelMaybe.lhs b/ghc/lib/std/PrelMaybe.lhs index 20de4cc..008a544 100644 --- a/ghc/lib/std/PrelMaybe.lhs +++ b/ghc/lib/std/PrelMaybe.lhs @@ -11,8 +11,17 @@ The @Maybe@ type. module PrelMaybe where import PrelBase +\end{code} + -data Maybe a = Nothing | Just a deriving (Eq, Ord, Show {- Read -}) +%********************************************************* +%* * +\subsection{Standard numeric classes} +%* * +%********************************************************* + +\begin{code} +data Maybe a = Nothing | Just a deriving (Eq, Ord) maybe :: b -> (a -> b) -> Maybe a -> b maybe n _ Nothing = n @@ -31,7 +40,21 @@ instance Monad Maybe where return = Just fail _ = Nothing +\end{code} + + +%********************************************************* +%* * +\subsection{Standard numeric classes} +%* * +%********************************************************* + +\begin{code} +data Either a b = Left a | Right b deriving (Eq, Ord ) +either :: (a -> c) -> (b -> c) -> Either a b -> c +either f _ (Left x) = f x +either _ g (Right y) = g y \end{code} diff --git a/ghc/lib/std/PrelNum.lhs b/ghc/lib/std/PrelNum.lhs index 96dc994..97c853c 100644 --- a/ghc/lib/std/PrelNum.lhs +++ b/ghc/lib/std/PrelNum.lhs @@ -9,12 +9,17 @@ module PrelNum where -import PrelBase -import Ix import {-# SOURCE #-} PrelErr +import PrelBase +import PrelList +import PrelEnum +import PrelShow infixr 8 ^, ^^, ** infixl 7 %, /, `quot`, `rem`, `div`, `mod` +infixl 7 * +infixl 6 +, - + \end{code} %********************************************************* @@ -24,6 +29,19 @@ infixl 7 %, /, `quot`, `rem`, `div`, `mod` %********************************************************* \begin{code} +class (Eq a, Show a) => Num a where + (+), (-), (*) :: a -> a -> a + negate :: a -> a + abs, signum :: a -> a + fromInteger :: Integer -> a + fromInt :: Int -> a -- partain: Glasgow extension + + x - y = x + negate y + negate x = 0 - x + fromInt (I# i#) = fromInteger (S# i#) + -- Go via the standard class-op if the + -- non-standard one ain't provided + class (Num a, Ord a) => Real a where toRational :: a -> Rational @@ -128,6 +146,23 @@ class (RealFrac a, Floating a) => RealFloat a where %********************************************************* \begin{code} +instance Num Int where + (+) x y = plusInt x y + (-) x y = minusInt x y + negate x = negateInt x + (*) x y = timesInt x y + abs n = if n `geInt` 0 then n else (negateInt n) + + signum n | n `ltInt` 0 = negateInt 1 + | n `eqInt` 0 = 0 + | otherwise = 1 + + fromInteger (S# i#) = I# i# + fromInteger (J# s# d#) + = case (integer2Int# s# d#) of { i# -> I# i# } + + fromInt n = n + instance Real Int where toRational x = toInteger x % 1 @@ -334,26 +369,6 @@ instance Show Integer where showList = showList__ (showsPrec 0) -instance Ix Integer where - range (m,n) - | m <= n = [m..n] - | otherwise = [] - - index b@(m,_) i - | inRange b i = fromInteger (i - m) - | otherwise = indexIntegerError i b - inRange (m,n) i = m <= i && i <= n - --- Sigh, really want to use helper function in Ix, but --- module deps. are too painful. -{-# NOINLINE indexIntegerError #-} -indexIntegerError :: Integer -> (Integer,Integer) -> a -indexIntegerError i rng - = error (showString "Ix{Integer}.index: Index " . - showParen True (showsPrec 0 i) . - showString " out of range " $ - showParen True (showsPrec 0 rng) "") - showSignedInteger :: Int -> Integer -> ShowS showSignedInteger p n r | n < 0 && p > 6 = '(':jtos n (')':r) @@ -370,6 +385,9 @@ jtos i rs | otherwise = jtos' q (chr (toInt r + (ord_0::Int)) : cs) where (q,r) = n `quotRem` 10 + +ord_0 :: Num a => a +ord_0 = fromInt (ord '0') \end{code} %********************************************************* @@ -413,6 +431,11 @@ denominator (_ :% y) = y %********************************************************* \begin{code} + +{-# SPECIALISE subtract :: Int -> Int -> Int #-} +subtract :: (Num a) => a -> a -> a +subtract x y = y - x + even, odd :: (Integral a) => a -> Bool even n = n `rem` 2 == 0 odd = not . even @@ -452,6 +475,5 @@ _ ^ _ = error "Prelude.^: negative exponent" Rational -> Int -> Rational #-} (^^) :: (Fractional a, Integral b) => a -> b -> a x ^^ n = if n >= 0 then x^n else recip (x^(negate n)) - \end{code} diff --git a/ghc/lib/std/PrelNumExtra.lhs b/ghc/lib/std/PrelNumExtra.lhs index f6163f6..de0ebc2 100644 --- a/ghc/lib/std/PrelNumExtra.lhs +++ b/ghc/lib/std/PrelNumExtra.lhs @@ -17,8 +17,10 @@ module PrelNumExtra where import PrelBase import PrelGHC +import PrelEnum +import PrelShow import PrelNum -import {-# SOURCE #-} PrelErr ( error ) +import PrelErr ( error ) import PrelList import PrelMaybe import Maybe ( fromMaybe ) @@ -256,14 +258,6 @@ instance RealFrac Double where {-# SPECIALIZE ceiling :: Double -> Integer #-} {-# SPECIALIZE floor :: Double -> Integer #-} -#if defined(__UNBOXED_INSTANCES__) - {-# SPECIALIZE properFraction :: Double -> (Int#, Double) #-} - {-# SPECIALIZE truncate :: Double -> Int# #-} - {-# SPECIALIZE round :: Double -> Int# #-} - {-# SPECIALIZE ceiling :: Double -> Int# #-} - {-# SPECIALIZE floor :: Double -> Int# #-} -#endif - properFraction x = case (decodeFloat x) of { (m,n) -> let b = floatRadix x in diff --git a/ghc/lib/std/PrelPack.hi-boot b/ghc/lib/std/PrelPack.hi-boot index 4f3189c..8abaa51 100644 --- a/ghc/lib/std/PrelPack.hi-boot +++ b/ghc/lib/std/PrelPack.hi-boot @@ -8,7 +8,7 @@ --------------------------------------------------------------------------- __interface PrelPack 1 where -__export ! PrelPack packCStringzh unpackCStringzh unpackNByteszh unpackAppendCStringzh unpackFoldrCStringzh ; +__export PrelPack packCStringzh unpackCStringzh unpackNByteszh unpackAppendCStringzh unpackFoldrCStringzh ; 1 packCStringzh :: [PrelBase.Char] -> PrelGHC.ByteArrayzh ; 1 unpackCStringzh :: PrelGHC.Addrzh -> [PrelBase.Char] ; diff --git a/ghc/lib/std/PrelPack.lhs b/ghc/lib/std/PrelPack.lhs index f126c56..5def573 100644 --- a/ghc/lib/std/PrelPack.lhs +++ b/ghc/lib/std/PrelPack.lhs @@ -51,6 +51,7 @@ import PrelBase import {-# SOURCE #-} PrelErr ( error ) import PrelList ( length ) import PrelST +import PrelNum import PrelArr import PrelAddr diff --git a/ghc/lib/std/PrelRead.lhs b/ghc/lib/std/PrelRead.lhs index a03963b..596b0c7 100644 --- a/ghc/lib/std/PrelRead.lhs +++ b/ghc/lib/std/PrelRead.lhs @@ -11,13 +11,14 @@ Instances of the Read class. module PrelRead where -import {-# SOURCE #-} PrelErr ( error ) +import PrelErr ( error ) +import PrelEnum ( Enum(..) ) import PrelNum import PrelNumExtra import PrelList import PrelTup import PrelMaybe -import PrelEither +import PrelShow -- isAlpha etc import PrelBase import Monad diff --git a/ghc/lib/std/PrelST.lhs b/ghc/lib/std/PrelST.lhs index a3a45a3..a45c8b2 100644 --- a/ghc/lib/std/PrelST.lhs +++ b/ghc/lib/std/PrelST.lhs @@ -9,8 +9,10 @@ module PrelST where import Monad +import PrelShow import PrelBase import PrelGHC +import PrelNum () -- So that we get the .hi file for system imports \end{code} %********************************************************* @@ -23,7 +25,8 @@ The state-transformer monad proper. By default the monad is strict; too many people got bitten by space leaks when it was lazy. \begin{code} -newtype ST s a = ST (State# s -> (# State# s, a #)) +newtype ST s a = ST (STRep s a) +type STRep s a = State# s -> (# State# s, a #) instance Functor (ST s) where fmap f (ST m) = ST $ \ s -> @@ -104,10 +107,16 @@ f = let All calls to @f@ will share a {\em single} array! End SLPJ 95/04. \begin{code} -{-# NOINLINE runST #-} +{-# INLINE runST #-} +-- The INLINE prevents runSTRep getting inlined in *this* module +-- so that it is still visible when runST is inlined in an importing +-- module. Regrettably delicate. runST is behaving like a wrapper. runST :: (forall s. ST s a) -> a -runST st = - case st of - ST m -> case m realWorld# of - (# _, r #) -> r +runST st = runSTRep (case st of { ST st_rep -> st_rep }) + +-- I'm letting runSTRep be inlined *after* full laziness +-- SLPJ Apr 99 +runSTRep :: (forall s. STRep s a) -> a +runSTRep st_rep = case st_rep realWorld# of + (# _, r #) -> r \end{code} diff --git a/ghc/lib/std/PrelShow.lhs b/ghc/lib/std/PrelShow.lhs new file mode 100644 index 0000000..eebdcc6 --- /dev/null +++ b/ghc/lib/std/PrelShow.lhs @@ -0,0 +1,347 @@ +% +% (c) The GRAP/AQUA Project, Glasgow University, 1992-1996 +% +\section{Module @PrelShow@} + + +\begin{code} +{-# OPTIONS -fno-implicit-prelude #-} + +module PrelShow + ( + Show(..), ShowS, + + -- Instances for Show: (), [], Bool, Ordering, Int, Char + + -- Show support code + shows, showChar, showString, showParen, showList__, showSpace, + showLitChar, protectEsc, + intToDigit, showSignedInt, + + -- Character operations + isAscii, isLatin1, isControl, isPrint, isSpace, isUpper, + isLower, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum, + toUpper, toLower, + asciiTab, + + -- String operations + lines, unlines, words, unwords + ) + where + +import {-# SOURCE #-} PrelErr ( error ) +import PrelBase +import PrelMaybe +import PrelList ( (!!), break, dropWhile ) +\end{code} + + + +%********************************************************* +%* * +\subsection{The @Show@ class} +%* * +%********************************************************* + +\begin{code} +type ShowS = String -> String + +class Show a where + showsPrec :: Int -> a -> ShowS + show :: a -> String + showList :: [a] -> ShowS + + showsPrec _ x s = show x ++ s + show x = shows x "" + showList ls = showList__ shows ls + +showList__ :: (a -> ShowS) -> [a] -> ShowS +showList__ _ [] s = "[]" ++ s +showList__ showx (x:xs) s = '[' : showx x (showl xs) + where + showl [] = ']' : s + showl (y:ys) = ',' : showx y (showl ys) +\end{code} + +%********************************************************* +%* * +\subsection{Simple Instances} +%* * +%********************************************************* + +\begin{code} + +instance Show () where + showsPrec _ () = showString "()" + +instance Show a => Show [a] where + showsPrec _ = showList + +instance Show Bool where + showsPrec _ True = showString "True" + showsPrec _ False = showString "False" + +instance Show Ordering where + showsPrec _ LT = showString "LT" + showsPrec _ EQ = showString "EQ" + showsPrec _ GT = showString "EQ" + +instance Show Char where + showsPrec _ '\'' = showString "'\\''" + showsPrec _ c = showChar '\'' . showLitChar c . showChar '\'' + + showList cs = showChar '"' . showl cs + where showl "" = showChar '"' + showl ('"':xs) = showString "\\\"" . showl xs + showl (x:xs) = showLitChar x . showl xs + +instance Show Int where + showsPrec p n = showSignedInt p n + +instance Show a => Show (Maybe a) where + showsPrec p Nothing = showString "Nothing" + showsPrec p (Just x) = showString "Just " . shows x + -- Not sure I have the priorities right here + +instance (Show a, Show b) => Show (Either a b) where + showsPrec p (Left a) = showString "Left " . shows a + showsPrec p (Right b) = showString "Right " . shows b + -- Not sure I have the priorities right here +\end{code} + + +%********************************************************* +%* * +\subsection{Show instances for the first few tuples +%* * +%********************************************************* + +\begin{code} +instance (Show a, Show b) => Show (a,b) where + showsPrec _ (x,y) = showChar '(' . shows x . showChar ',' . + shows y . showChar ')' + +instance (Show a, Show b, Show c) => Show (a, b, c) where + showsPrec _ (x,y,z) = showChar '(' . shows x . showChar ',' . + shows y . showChar ',' . + shows z . showChar ')' + +instance (Show a, Show b, Show c, Show d) => Show (a, b, c, d) where + showsPrec _ (w,x,y,z) = showChar '(' . shows w . showChar ',' . + shows x . showChar ',' . + shows y . showChar ',' . + shows z . showChar ')' + +instance (Show a, Show b, Show c, Show d, Show e) => Show (a, b, c, d, e) where + showsPrec _ (v,w,x,y,z) = showChar '(' . shows v . showChar ',' . + shows w . showChar ',' . + shows x . showChar ',' . + shows y . showChar ',' . + shows z . showChar ')' +\end{code} + + +%********************************************************* +%* * +\subsection{Support code for @Show@} +%* * +%********************************************************* + +\begin{code} +shows :: (Show a) => a -> ShowS +shows = showsPrec zeroInt + +showChar :: Char -> ShowS +showChar = (:) + +showString :: String -> ShowS +showString = (++) + +showParen :: Bool -> ShowS -> ShowS +showParen b p = if b then showChar '(' . p . showChar ')' else p + +showSpace :: ShowS +showSpace = {-showChar ' '-} \ xs -> ' ' : xs +\end{code} + +Code specific for characters + +\begin{code} +showLitChar :: Char -> ShowS +showLitChar c | c > '\DEL' = showChar '\\' . protectEsc isDigit (shows (ord c)) +showLitChar '\DEL' = showString "\\DEL" +showLitChar '\\' = showString "\\\\" +showLitChar c | c >= ' ' = showChar c +showLitChar '\a' = showString "\\a" +showLitChar '\b' = showString "\\b" +showLitChar '\f' = showString "\\f" +showLitChar '\n' = showString "\\n" +showLitChar '\r' = showString "\\r" +showLitChar '\t' = showString "\\t" +showLitChar '\v' = showString "\\v" +showLitChar '\SO' = protectEsc (== 'H') (showString "\\SO") +showLitChar c = showString ('\\' : asciiTab!!ord c) + +protectEsc :: (Char -> Bool) -> ShowS -> ShowS +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' `plusInt` I# i `minusInt` I# 10#) + | otherwise = error ("Char.intToDigit: not a digit " ++ show (I# i)) + +\end{code} + +Code specific for Ints. + +\begin{code} +showSignedInt :: Int -> Int -> ShowS +showSignedInt (I# p) (I# n) r + | n <# 0# && p ># 6# = '(':itos n (')':r) + | otherwise = itos n r + +itos :: Int# -> String -> String +itos n r + | n >=# 0# = itos' n r + | negateInt# n <# 0# = -- n is minInt, a difficult number + itos (n `quotInt#` 10#) (itos' (negateInt# (n `remInt#` 10#)) r) + | otherwise = '-':itos' (negateInt# n) r + where + itos' :: Int# -> String -> String + -- x >= 0 + itos' x cs + | x <# 10# = C# (chr# (x +# ord# '0'#)) : cs + | otherwise = itos' (x `quotInt#` 10#) + (C# (chr# (x `remInt#` 10# +# ord# '0'#)) : cs) +\end{code} + + + +%********************************************************* +%* * +\subsection{Character stuff} +%* * +%********************************************************* + +\begin{code} +isAscii, isLatin1, isControl, isPrint, isSpace, isUpper, + isLower, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum :: 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 PrelList 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"] +\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} diff --git a/ghc/lib/std/PrelTup.lhs b/ghc/lib/std/PrelTup.lhs index c375eb7..34dbfa8 100644 --- a/ghc/lib/std/PrelTup.lhs +++ b/ghc/lib/std/PrelTup.lhs @@ -23,10 +23,10 @@ import PrelBase %********************************************************* \begin{code} -data (,) a b = (,) a b deriving (Eq, Ord, Bounded) -data (,,) a b c = (,,) a b c deriving (Eq, Ord, Bounded) -data (,,,) a b c d = (,,,) a b c d deriving (Eq, Ord, Bounded) -data (,,,,) a b c d e = (,,,,) a b c d e deriving (Eq, Ord, Bounded) +data (,) a b = (,) a b deriving (Eq, Ord) +data (,,) a b c = (,,) a b c deriving (Eq, Ord) +data (,,,) a b c d = (,,,) a b c d deriving (Eq, Ord) +data (,,,,) a b c d e = (,,,,) a b c d e deriving (Eq, Ord) data (,,,,,) a b c d e f = (,,,,,) a b c d e f data (,,,,,,) a b c d e f g = (,,,,,,) a b c d e f g data (,,,,,,,) a b c d e f g h = (,,,,,,,) a b c d e f g h @@ -82,37 +82,6 @@ data (,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,) a b c d e f g h i j k l m n o p q r = (,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,) a b c d e f g h i j k l m n o p q r s t u v w x y z a_ b_ c_ d_ e_ f_ g_ h_ i_ j_ k_ \end{code} -@Show@ instances for just the first few. - -\begin{code} -instance (Show a, Show b) => Show (a,b) where - showsPrec _ (x,y) = showChar '(' . shows x . showChar ',' . - shows y . showChar ')' - showList = showList__ (showsPrec 0) - -instance (Show a, Show b, Show c) => Show (a, b, c) where - showsPrec _ (x,y,z) = showChar '(' . showsPrec 0 x . showChar ',' . - showsPrec 0 y . showChar ',' . - showsPrec 0 z . showChar ')' - showList = showList__ (showsPrec 0) - -instance (Show a, Show b, Show c, Show d) => Show (a, b, c, d) where - showsPrec _ (w,x,y,z) = showChar '(' . showsPrec 0 w . showChar ',' . - showsPrec 0 x . showChar ',' . - showsPrec 0 y . showChar ',' . - showsPrec 0 z . showChar ')' - - showList = showList__ (showsPrec 0) - -instance (Show a, Show b, Show c, Show d, Show e) => Show (a, b, c, d, e) where - showsPrec _ (v,w,x,y,z) = showChar '(' . showsPrec 0 v . showChar ',' . - showsPrec 0 w . showChar ',' . - showsPrec 0 x . showChar ',' . - showsPrec 0 y . showChar ',' . - showsPrec 0 z . showChar ')' - showList = showList__ (showsPrec 0) -\end{code} - %********************************************************* %* * diff --git a/ghc/lib/std/Prelude.lhs b/ghc/lib/std/Prelude.lhs index 60b292e..71a0378 100644 --- a/ghc/lib/std/Prelude.lhs +++ b/ghc/lib/std/Prelude.lhs @@ -7,8 +7,10 @@ and Prelude.-> (as they are normally). -- SDM 8/10/97 module Prelude ( - -- Everything from these modules - module PrelList, + -- Everything corresponding to the Report's PreludeList + module PrelList, + lines, words, unlines, unwords, + sum, product, -- Everything corresponding to the Report's PreludeText ReadS, ShowS, @@ -68,12 +70,12 @@ module Prelude ( import PrelBase import PrelList hiding ( takeUInt_append ) import PrelRead +import PrelEnum import PrelNum import PrelNumExtra import PrelTup import PrelMaybe -import PrelEither -import PrelBounded +import PrelShow import PrelConc import Monad import Maybe @@ -94,4 +96,25 @@ undefined = error "Prelude.undefined" \end{code} +List sum and product are defined here because PrelList is too far +down the compilation chain to "see" the Num class. +\begin{code} +-- sum and product compute the sum or product of a finite list of numbers. +{-# SPECIALISE sum :: [Int] -> Int #-} +{-# SPECIALISE product :: [Int] -> Int #-} +sum, product :: (Num a) => [a] -> a +#ifdef USE_REPORT_PRELUDE +sum = foldl (+) 0 +product = foldl (*) 1 +#else +sum l = sum' l 0 + where + sum' [] a = a + sum' (x:xs) a = sum' xs (a+x) +product l = prod l 1 + where + prod [] a = a + prod (x:xs) a = prod xs (a*x) +#endif +\end{code} diff --git a/ghc/lib/std/Random.lhs b/ghc/lib/std/Random.lhs index 3a2f3b0..e6135c2 100644 --- a/ghc/lib/std/Random.lhs +++ b/ghc/lib/std/Random.lhs @@ -31,6 +31,7 @@ module Random import CPUTime (getCPUTime) import PrelST import PrelRead +import PrelShow import PrelIOBase import PrelNumExtra ( float2Double, double2Float ) import PrelBase diff --git a/ghc/lib/std/Time.lhs b/ghc/lib/std/Time.lhs index e8201e2..fb6b3fe 100644 --- a/ghc/lib/std/Time.lhs +++ b/ghc/lib/std/Time.lhs @@ -38,6 +38,7 @@ module Time import PreludeBuiltin #else import PrelBase +import PrelShow import PrelIOBase import PrelHandle import PrelArr -- 1.7.10.4