[project @ 2001-08-21 14:44:22 by simonmar]
[ghc-hetmet.git] / ghc / lib / std / PrelList.lhs
index 27d0d4f..88636bc 100644 (file)
@@ -1,5 +1,5 @@
 % ------------------------------------------------------------------------------
-% $Id: PrelList.lhs,v 1.22 2000/09/14 13:46:42 simonpj Exp $
+% $Id: PrelList.lhs,v 1.25 2001/07/31 10:48:02 simonmar Exp $
 %
 % (c) The University of Glasgow, 1994-2000
 %
@@ -157,9 +157,15 @@ filterList pred (x:xs)
 -- scanl1 is similar, again without the starting element:
 --      scanl1 f [x1, x2, ...] == [x1, x1 `f` x2, ...]
 
-foldl                   :: (a -> b -> a) -> a -> [b] -> a
-foldl _ z []            =  z
-foldl f z (x:xs)        =  foldl f (f z x) xs
+-- We write foldl as a non-recursive thing, so that it
+-- can be inlined, and then (often) strictness-analysed,
+-- and hence the classic space leak on foldl (+) 0 xs
+
+foldl        :: (a -> b -> a) -> a -> [b] -> a
+foldl f z xs = lgo z xs
+            where
+               lgo z []     =  z
+               lgo z (x:xs) = lgo (f z x) xs
 
 foldl1                  :: (a -> a -> a) -> [a] -> a
 foldl1 f (x:xs)         =  foldl f x xs
@@ -255,23 +261,17 @@ dropWhile p xs@(x:xs')
 -- is equivalent to (take n xs, drop n xs).
 #ifdef USE_REPORT_PRELUDE
 take                   :: Int -> [a] -> [a]
-take 0 _               =  []
+take n _      | n <= 0 =  []
 take _ []              =  []
-take n (x:xs) | n > 0  =  x : take (minusInt n 1) xs
-take _     _           =  errorNegativeIdx "take"
+take n (x:xs)          =  x : take (n-1) xs
 
 drop                   :: Int -> [a] -> [a]
-drop 0 xs              =  xs
+drop n xs     | n <= 0 =  xs
 drop _ []              =  []
-drop n (_:xs) | n > 0  =  drop (minusInt n 1) xs
-drop _     _           =  errorNegativeIdx "drop"
-
+drop n (_:xs)          =  drop (n-1) xs
 
-splitAt                   :: Int -> [a] -> ([a],[a])
-splitAt 0 xs              =  ([],xs)
-splitAt _ []              =  ([],[])
-splitAt n (x:xs) | n > 0  =  (x:xs',xs'') where (xs',xs'') = splitAt (minusInt n 1) xs
-splitAt _     _           =  errorNegativeIdx "splitAt"
+splitAt                  :: Int -> [a] -> ([a],[a])
+splitAt n xs             =  (take n xs, drop n xs)
 
 #else /* hack away */
 take   :: Int -> [b] -> [b]
@@ -284,7 +284,7 @@ take (I# n#) xs = takeUInt n# xs
 takeUInt :: Int# -> [b] -> [b]
 takeUInt n xs
   | n >=# 0#  =  take_unsafe_UInt n xs
-  | otherwise =  errorNegativeIdx "take"
+  | otherwise =  []
 
 take_unsafe_UInt :: Int# -> [b] -> [b]
 take_unsafe_UInt 0#  _  = []
@@ -296,7 +296,7 @@ take_unsafe_UInt m   ls =
 takeUInt_append :: Int# -> [b] -> [b] -> [b]
 takeUInt_append n xs rs
   | n >=# 0#  =  take_unsafe_UInt_append n xs rs
-  | otherwise =  errorNegativeIdx "take"
+  | otherwise =  []
 
 take_unsafe_UInt_append        :: Int# -> [b] -> [b] -> [b]
 take_unsafe_UInt_append        0#  _ rs  = rs
@@ -307,7 +307,7 @@ take_unsafe_UInt_append     m  ls rs  =
 
 drop           :: Int -> [b] -> [b]
 drop (I# n#) ls
-  | n# <# 0#   = errorNegativeIdx "drop"
+  | n# <# 0#   = []
   | otherwise  = drop# n# ls
     where
        drop# :: Int# -> [a] -> [a]
@@ -317,7 +317,7 @@ drop (I# n#) ls
 
 splitAt        :: Int -> [b] -> ([b], [b])
 splitAt (I# n#) ls
-  | n# <# 0#   = errorNegativeIdx "splitAt"
+  | n# <# 0#   = ([], ls)
   | otherwise  = splitAt# n# ls
     where
        splitAt# :: Int# -> [a] -> ([a], [a])
@@ -509,7 +509,7 @@ I'm going to leave it though.
 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
+tuples are in the List module.
 
 \begin{code}
 ----------------------------------------------
@@ -595,10 +595,6 @@ errorEmptyList :: String -> a
 errorEmptyList fun =
   error (prel_list_str ++ fun ++ ": empty list")
 
-errorNegativeIdx :: String -> a
-errorNegativeIdx fun =
- error (prel_list_str ++ fun ++ ": negative index")
-
 prel_list_str :: String
 prel_list_str = "Prelude."
 \end{code}