\begin{code}
-{-# OPTIONS -fno-implicit-prelude #-}
+{-# OPTIONS_GHC -fno-implicit-prelude #-}
-----------------------------------------------------------------------------
-- |
-- Module : GHC.List
--
-----------------------------------------------------------------------------
+-- #hide
module GHC.List (
-- [] (..), -- Not Haskell 98; built in syntax
map, (++), filter, concat,
head, last, tail, init, null, length, (!!),
- foldl, foldl1, scanl, scanl1, foldr, foldr1, scanr, scanr1,
+ foldl, scanl, scanl1, foldr, foldr1, scanr, scanr1,
iterate, repeat, replicate, cycle,
take, drop, splitAt, takeWhile, dropWhile, span, break,
reverse, and, or,
any, all, elem, notElem, lookup,
- maximum, minimum, concatMap,
+ concatMap,
zip, zip3, zipWith, zipWith3, unzip, unzip3,
-#ifdef USE_REPORT_PRELUDE
-
-#else
+ errorEmptyList,
+#ifndef USE_REPORT_PRELUDE
-- non-standard, but hidden when creating the Prelude
-- export list.
takeUInt_append
-
#endif
) where
import {-# SOURCE #-} GHC.Err ( error )
-import Data.Tuple
+import Data.Tuple() -- Instances
import Data.Maybe
import GHC.Base
-- This rule is useful in cases like
-- head [y | (x,y) <- ps, x==t]
{-# RULES
-"head/build" forall (g::forall b.(Bool->b->b)->b->b) .
+"head/build" forall (g::forall b.(a->b->b)->b->b) .
head (build g) = g (\x _ -> x) badHead
"head/augment" forall xs (g::forall b. (a->b->b) -> b -> b) .
head (augment g xs) = g (\x _ -> x) (head xs)
lgo z [] = z
lgo z (x:xs) = lgo (f z x) xs
--- | 'foldl1' is a variant of 'foldl' that has no starting value argument,
--- and thus must be applied to non-empty lists.
-
-foldl1 :: (a -> a -> a) -> [a] -> a
-foldl1 f (x:xs) = foldl f x xs
-foldl1 _ [] = errorEmptyList "foldl1"
-
-- | 'scanl' is similar to 'foldl', but returns a list of successive
-- reduced values from the left:
--
-- every element.
-- It is an instance of the more general 'Data.List.genericReplicate',
-- in which @n@ may be of any integral type.
+{-# INLINE replicate #-}
replicate :: Int -> a -> [a]
replicate n x = take n (repeat x)
splitAt n xs = (take n xs, drop n xs)
#else /* hack away */
+{-# RULES
+"take" [~1] forall n xs . take n xs = case n of I# n# -> build (\c nil -> foldr (takeFB c nil) (takeConst nil) xs n#)
+"takeList" [1] forall n xs . foldr (takeFB (:) []) (takeConst []) xs n = takeUInt n xs
+ #-}
+
+{-# NOINLINE [0] takeConst #-}
+-- just a version of const that doesn't get inlined too early, so we
+-- can spot it in rules. Also we need a type sig due to the unboxed Int#.
+takeConst :: a -> Int# -> a
+takeConst x _ = x
+
+{-# NOINLINE [0] takeFB #-}
+takeFB :: (a -> b -> c) -> c -> a -> (Int# -> b) -> Int# -> c
+takeFB c n x xs m | m <=# 0# = n
+ | otherwise = x `c` xs (m -# 1#)
+
+{-# INLINE [0] take #-}
take (I# n#) xs = takeUInt n# xs
-- The general code for take, below, checks n <= maxInt
(x:xs) -> x : take_unsafe_UInt_append (m -# 1#) xs rs
drop (I# n#) ls
- | n# <# 0# = []
+ | n# <# 0# = ls
| otherwise = drop# n# ls
where
drop# :: Int# -> [a] -> [a]
| key == x = Just y
| otherwise = lookup key xys
-{-# SPECIALISE maximum :: [Int] -> Int #-}
-{-# SPECIALISE minimum :: [Int] -> Int #-}
-
--- | 'maximum' returns the maximum value from a list,
--- which must be non-empty, finite, and of an ordered type.
--- It is a special case of 'Data.List.maximumBy', which allows the
--- programmer to supply their own comparison function.
-maximum :: (Ord a) => [a] -> a
-maximum [] = errorEmptyList "maximum"
-maximum xs = foldl1 max xs
-
--- | 'minimum' returns the minimum value from a list,
--- which must be non-empty, finite, and of an ordered type.
--- It is a special case of 'Data.List.minimumBy', which allows the
--- programmer to supply their own comparison function.
-minimum :: (Ord a) => [a] -> a
-minimum [] = errorEmptyList "minimum"
-minimum xs = foldl1 min xs
-
-- | Map a function over a list and concatenate the results.
concatMap :: (a -> [b]) -> [a] -> [b]
concatMap f = foldr ((++) . f) []