(original) (raw)

{-# LANGUAGE Trustworthy #-} {-# LANGUAGE CPP, NoImplicitPrelude, ScopedTypeVariables, MagicHash #-} {-# LANGUAGE BangPatterns #-}

module GHC.List (

map, (++), filter, concat, head, last, tail, init, uncons, null, length, (!!), foldl, foldl', foldl1, foldl1', scanl, scanl1, scanl', foldr, foldr1, scanr, scanr1, iterate, iterate', repeat, replicate, cycle, take, drop, sum, product, maximum, minimum, splitAt, takeWhile, dropWhile, span, break, reverse, and, or, any, all, elem, notElem, lookup, concatMap, zip, zip3, zipWith, zipWith3, unzip, unzip3, errorEmptyList,

) where

import Data.Maybe import GHC.Base import GHC.Num (Num(..)) import GHC.Integer (Integer)

infixl 9 !! infix 4 [elem](GHC.List.html#elem), [notElem](GHC.List.html#notElem)

head :: [a] -> a head (x:_) = x head [] = badHead {-# NOINLINE [1] head #-}

badHead :: a badHead = errorEmptyList "head"

{-# RULES "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) #-}

uncons :: [a] -> Maybe (a, [a]) uncons [] = Nothing uncons (x:xs) = Just (x, xs)

tail :: [a] -> [a] tail (_:xs) = xs tail [] = errorEmptyList "tail"

last :: [a] -> a #if defined(USE_REPORT_PRELUDE) last [x] = x last (_:xs) = last xs last [] = errorEmptyList "last" #else

last xs = foldl (_ x -> x) lastError xs {-# INLINE last #-}

lastError :: a lastError = errorEmptyList "last" #endif

init :: [a] -> [a] #if defined(USE_REPORT_PRELUDE) init [x] = [] init (x:xs) = x : init xs init [] = errorEmptyList "init" #else

init [] = errorEmptyList "init" init (x:xs) = init' x xs where init' _ [] = [] init' y (z:zs) = y : init' z zs #endif

null :: [a] -> Bool null [] = True null (:) = False

{-# NOINLINE [1] length #-} length :: [a] -> Int length xs = lenAcc xs 0

lenAcc :: [a] -> Int -> Int lenAcc [] n = n lenAcc (_:ys) n = lenAcc ys (n+1)

{-# RULES "length" [~1] forall xs . length xs = foldr lengthFB idLength xs 0 "lengthList" [1] foldr lengthFB idLength = lenAcc #-}

{-# INLINE [0] lengthFB #-} lengthFB :: x -> (Int -> Int) -> Int -> Int lengthFB _ r = \ a -> r (a + 1)

{-# INLINE [0] idLength #-} idLength :: Int -> Int idLength = id

{-# NOINLINE [1] filter #-} filter :: (a -> Bool) -> [a] -> [a] filter _pred [] = [] filter pred (x:xs) | pred x = x : filter pred xs | otherwise = filter pred xs

{-# INLINE [0] filterFB #-} filterFB :: (a -> b -> b) -> (a -> Bool) -> a -> b -> b filterFB c p x r | p x = x [c](#local-6989586621679029792) r | otherwise = r

{-# RULES "filter" [~1] forall p xs. filter p xs = build (\c n -> foldr (filterFB c p) n xs) "filterList" [1] forall p. foldr (filterFB (:) p) [] = filter p "filterFB" forall c p q. filterFB (filterFB c p) q = filterFB c (\x -> q x && p x) #-}

foldl :: forall a b. (b -> a -> b) -> b -> [a] -> b {-# INLINE foldl #-} foldl k z0 xs = foldr ((v::a) (fn::b->b) -> oneShot ((z::b) -> fn (k z v))) (id :: b -> b) xs z0

foldl' :: forall a b . (b -> a -> b) -> b -> [a] -> b {-# INLINE foldl' #-} foldl' k z0 xs = foldr ((v::a) (fn::b->b) -> oneShot ((z::b) -> z seq fn (k z v))) (id :: b -> b) xs z0

foldl1 :: (a -> a -> a) -> [a] -> a foldl1 f (x:xs) = foldl f x xs foldl1 _ [] = errorEmptyList "foldl1"

foldl1' :: (a -> a -> a) -> [a] -> a foldl1' f (x:xs) = foldl' f x xs foldl1' _ [] = errorEmptyList "foldl1'"

sum :: (Num a) => [a] -> a {-# INLINE sum #-} sum = foldl (+) 0

product :: (Num a) => [a] -> a {-# INLINE product #-} product = foldl (*) 1

{-# NOINLINE [1] scanl #-} scanl :: (b -> a -> b) -> b -> [a] -> [b] scanl = scanlGo where scanlGo :: (b -> a -> b) -> b -> [a] -> [b] scanlGo f q ls = q : (case ls of [] -> [] x:xs -> scanlGo f (f q x) xs)

{-# RULES "scanl" [~1] forall f a bs . scanl f a bs = build (\c n -> a c foldr (scanlFB f c) (constScanl n) bs a) "scanlList" [1] forall f (a::a) bs . foldr (scanlFB f (:)) (constScanl []) bs a = tail (scanl f a bs) #-}

{-# INLINE [0] scanlFB #-} scanlFB :: (b -> a -> b) -> (b -> c -> c) -> a -> (b -> c) -> b -> c scanlFB f c = [b](#local-6989586621679029824) g -> oneShot ([x](#local-6989586621679029826) -> let b' = f x b in b' [c](#local-6989586621679029823) g b')

{-# INLINE [0] constScanl #-} constScanl :: a -> b -> a constScanl = const

scanl1 :: (a -> a -> a) -> [a] -> [a] scanl1 f (x:xs) = scanl f x xs scanl1 _ [] = []

{-# NOINLINE [1] scanl' #-} scanl' :: (b -> a -> b) -> b -> [a] -> [b]

scanl' = scanlGo' where scanlGo' :: (b -> a -> b) -> b -> [a] -> [b] scanlGo' f q ls = q : (case ls of [] -> [] x:xs -> scanlGo' f (f q x) xs)

{-# RULES "scanl'" [~1] forall f a bs . scanl' f a bs = build (\c n -> a c foldr (scanlFB' f c) (flipSeqScanl' n) bs a) "scanlList'" [1] forall f a bs . foldr (scanlFB' f (:)) (flipSeqScanl' []) bs a = tail (scanl' f a bs) #-}

{-# INLINE [0] scanlFB' #-} scanlFB' :: (b -> a -> b) -> (b -> c -> c) -> a -> (b -> c) -> b -> c scanlFB' f c = [b](#local-6989586621679029841) g -> oneShot ([x](#local-6989586621679029843) -> let b' = f x b in b' [c](#local-6989586621679029840) g b')

{-# INLINE [0] flipSeqScanl' #-} flipSeqScanl' :: a -> b -> a flipSeqScanl' a _b = a

foldr1 :: (a -> a -> a) -> [a] -> a foldr1 f = go where go [x] = x go (x:xs) = f x (go xs) go [] = errorEmptyList "foldr1" {-# INLINE [0] foldr1 #-}

{-# NOINLINE [1] scanr #-} scanr :: (a -> b -> b) -> b -> [a] -> [b] scanr _ q0 [] = [q0] scanr f q0 (x:xs) = f x q : qs where qs@(q:_) = scanr f q0 xs

{-# INLINE [0] strictUncurryScanr #-} strictUncurryScanr :: (a -> b -> c) -> (a, b) -> c strictUncurryScanr f pair = case pair of (x, y) -> f x y

{-# INLINE [0] scanrFB #-} scanrFB :: (a -> b -> b) -> (b -> c -> c) -> a -> (b, c) -> (b, c) scanrFB f c = [x](#local-6989586621679029865) (r, est) -> (f x r, r [c](#local-6989586621679029864) est)

{-# RULES "scanr" [~1] forall f q0 ls . scanr f q0 ls = build (\c n -> strictUncurryScanr c (foldr (scanrFB f c) (q0,n) ls)) "scanrList" [1] forall f q0 ls . strictUncurryScanr (:) (foldr (scanrFB f (:)) (q0,[]) ls) = scanr f q0 ls #-}

scanr1 :: (a -> a -> a) -> [a] -> [a] scanr1 _ [] = [] scanr1 _ [x] = [x] scanr1 f (x:xs) = f x q : qs where qs@(q:_) = scanr1 f xs

maximum :: (Ord a) => [a] -> a {-# INLINABLE maximum #-} maximum [] = errorEmptyList "maximum" maximum xs = foldl1 max xs

{-# SPECIALIZE maximum :: [Int] -> Int #-} {-# SPECIALIZE maximum :: [Integer] -> Integer #-}

minimum :: (Ord a) => [a] -> a {-# INLINABLE minimum #-} minimum [] = errorEmptyList "minimum" minimum xs = foldl1 min xs

{-# SPECIALIZE minimum :: [Int] -> Int #-} {-# SPECIALIZE minimum :: [Integer] -> Integer #-}

{-# NOINLINE [1] iterate #-} iterate :: (a -> a) -> a -> [a] iterate f x = x : iterate f (f x)

{-# INLINE [0] iterateFB #-} iterateFB :: (a -> b -> b) -> (a -> a) -> a -> b iterateFB c f x0 = go x0 where go x = x [c](#local-6989586621679029878) go (f x)

{-# RULES "iterate" [~1] forall f x. iterate f x = build (\c _n -> iterateFB c f x) "iterateFB" [1] iterateFB (:) = iterate #-}

{-# NOINLINE [1] iterate' #-} iterate' :: (a -> a) -> a -> [a] iterate' f x = let x' = f x in x' seq (x : iterate' f x')

{-# INLINE [0] iterate'FB #-} iterate'FB :: (a -> b -> b) -> (a -> a) -> a -> b iterate'FB c f x0 = go x0 where go x = let x' = f x in x' seq (x [c](#local-6989586621679029886) go x')

{-# RULES "iterate'" [~1] forall f x. iterate' f x = build (\c _n -> iterate'FB c f x) "iterate'FB" [1] iterate'FB (:) = iterate' #-}

repeat :: a -> [a] {-# INLINE [0] repeat #-}

repeat x = xs where xs = x : xs

{-# INLINE [0] repeatFB #-}
repeatFB :: (a -> b -> b) -> a -> b repeatFB c x = xs where xs = x [c](#local-6989586621679029894) xs

{-# RULES "repeat" [~1] forall x. repeat x = build (\c _n -> repeatFB c x) "repeatFB" [1] repeatFB (:) = repeat #-}

{-# INLINE replicate #-} replicate :: Int -> a -> [a] replicate n x = take n (repeat x)

cycle :: [a] -> [a] cycle [] = errorEmptyList "cycle" cycle xs = xs' where xs' = xs ++ xs'

{-# NOINLINE [1] takeWhile #-} takeWhile :: (a -> Bool) -> [a] -> [a] takeWhile _ [] = [] takeWhile p (x:xs) | p x = x : takeWhile p xs | otherwise = []

{-# INLINE [0] takeWhileFB #-} takeWhileFB :: (a -> Bool) -> (a -> b -> b) -> b -> a -> b -> b takeWhileFB p c n = [x](#local-6989586621679029907) r -> if p x then x [c](#local-6989586621679029905) r else n

{-# RULES "takeWhile" [~1] forall p xs. takeWhile p xs = build (\c n -> foldr (takeWhileFB p c n) n xs) "takeWhileList" [1] forall p. foldr (takeWhileFB p (:) []) [] = takeWhile p "takeWhileFB" forall c n p q. takeWhileFB q (takeWhileFB p c n) n = takeWhileFB (\x -> q x && p x) c n #-}

dropWhile :: (a -> Bool) -> [a] -> [a] dropWhile _ [] = [] dropWhile p xs@(x:xs') | p x = dropWhile p xs' | otherwise = xs

take :: Int -> [a] -> [a] #if defined(USE_REPORT_PRELUDE) take n _ | n <= 0 = [] take _ [] = [] take n (x:xs) = x : take (n-1) xs #else

{-# INLINE [1] take #-} take n xs | 0 < n = unsafeTake n xs | otherwise = []

{-# NOINLINE [1] unsafeTake #-} unsafeTake :: Int -> [a] -> [a] unsafeTake !_ [] = [] unsafeTake 1 (x: _) = [x] unsafeTake m (x:xs) = x : unsafeTake (m - 1) xs

{-# RULES "take" [~1] forall n xs . take n xs = build (\c nil -> if 0 < n then foldr (takeFB c nil) (flipSeqTake nil) xs n else nil) "unsafeTakeList" [1] forall n xs . foldr (takeFB (:) []) (flipSeqTake []) xs n = unsafeTake n xs #-}

{-# INLINE [0] flipSeqTake #-}

flipSeqTake :: a -> Int -> a flipSeqTake x _n = x

{-# INLINE [0] takeFB #-} takeFB :: (a -> b -> b) -> b -> a -> (Int -> b) -> Int -> b

takeFB c n x xs = \ m -> case m of 1 -> x [c](#local-6989586621679029921) n _ -> x [c](#local-6989586621679029921) xs (m - 1) #endif

drop :: Int -> [a] -> [a] #if defined(USE_REPORT_PRELUDE) drop n xs | n <= 0 = xs drop _ [] = [] drop n (_:xs) = drop (n-1) xs #else /* hack away */ {-# INLINE drop #-} drop n ls | n <= 0 = ls | otherwise = unsafeDrop n ls where

unsafeDrop :: Int -> [[a](#local-6989586621679029929)] -> [[a](#local-6989586621679029929)]
[unsafeDrop](#local-6989586621679029928) !_ []     = []
unsafeDrop 1  (_:[xs](#local-6989586621679029930)) = [xs](#local-6989586621679029930)
unsafeDrop [m](#local-6989586621679029931)  (_:[xs](#local-6989586621679029932)) = [unsafeDrop](#local-6989586621679029928) ([m](#local-6989586621679029931) - 1) [xs](#local-6989586621679029932)

#endif

splitAt :: Int -> [a] -> ([a],[a])

#if defined(USE_REPORT_PRELUDE) splitAt n xs = (take n xs, drop n xs) #else splitAt n ls | n <= 0 = ([], ls) | otherwise = splitAt' n ls where splitAt' :: Int -> [a] -> ([a], [a]) splitAt' _ [] = ([], []) splitAt' 1 (x:xs) = ([x], xs) splitAt' m (x:xs) = (x:xs', xs'') where (xs', xs'') = splitAt' (m - 1) xs #endif /* USE_REPORT_PRELUDE */

span :: (a -> Bool) -> [a] -> ([a],[a]) span _ xs@[] = (xs, xs) span p xs@(x:xs') | p x = let (ys,zs) = span p xs' in (x:ys,zs) | otherwise = ([],xs)

break :: (a -> Bool) -> [a] -> ([a],[a]) #if defined(USE_REPORT_PRELUDE) break p = span (not . p) #else

break _ xs@[] = (xs, xs) break p xs@(x:xs') | p x = ([],xs) | otherwise = let (ys,zs) = break p xs' in (x:ys,zs) #endif

reverse :: [a] -> [a] #if defined(USE_REPORT_PRELUDE) reverse = foldl (flip (:)) [] #else reverse l = rev l [] where rev [] a = a rev (x:xs) a = rev xs (x:a) #endif

and :: [Bool] -> Bool #if defined(USE_REPORT_PRELUDE) and = foldr (&&) True #else and [] = True and (x:xs) = x && and xs {-# NOINLINE [1] and #-}

{-# RULES "and/build" forall (g::forall b.(Bool->b->b)->b->b) . and (build g) = g (&&) True #-} #endif

or :: [Bool] -> Bool #if defined(USE_REPORT_PRELUDE) or = foldr (||) False #else or [] = False or (x:xs) = x || or xs {-# NOINLINE [1] or #-}

{-# RULES "or/build" forall (g::forall b.(Bool->b->b)->b->b) . or (build g) = g (||) False #-} #endif

any :: (a -> Bool) -> [a] -> Bool

#if defined(USE_REPORT_PRELUDE) any p = or . map p #else any _ [] = False any p (x:xs) = p x || any p xs

{-# NOINLINE [1] any #-}

{-# RULES "any/build" forall p (g::forall b.(a->b->b)->b->b) . any p (build g) = g ((||) . p) False #-} #endif

all :: (a -> Bool) -> [a] -> Bool #if defined(USE_REPORT_PRELUDE) all p = and . map p #else all _ [] = True all p (x:xs) = p x && all p xs

{-# NOINLINE [1] all #-}

{-# RULES "all/build" forall p (g::forall b.(a->b->b)->b->b) . all p (build g) = g ((&&) . p) True #-} #endif

elem :: (Eq a) => a -> [a] -> Bool #if defined(USE_REPORT_PRELUDE) elem x = any (== x) #else elem _ [] = False elem x (y:ys) = x==y || elem x ys {-# NOINLINE [1] elem #-} {-# RULES "elem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) . elem x (build g) = g (\ y r -> (x == y) || r) False #-} #endif

notElem :: (Eq a) => a -> [a] -> Bool #if defined(USE_REPORT_PRELUDE) notElem x = all (/= x) #else notElem _ [] = True notElem x (y:ys)= x /= y && notElem x ys {-# NOINLINE [1] notElem #-} {-# RULES "notElem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) . notElem x (build g) = g (\ y r -> (x /= y) && r) True #-} #endif

lookup :: (Eq a) => a -> [(a,b)] -> Maybe b lookup _key [] = Nothing lookup key ((x,y):xys) | key == x = Just y | otherwise = lookup key xys

concatMap :: (a -> [b]) -> [a] -> [b] concatMap f = foldr ((++) . f) []

{-# NOINLINE [1] concatMap #-}

{-# RULES "concatMap" forall f xs . concatMap f xs = build (\c n -> foldr (\x b -> foldr c b (f x)) n xs) #-}

concat :: [[a]] -> [a] concat = foldr (++) []

{-# NOINLINE [1] concat #-}

{-# RULES "concat" forall xs. concat xs = build (\c n -> foldr (\x y -> foldr c y x) n xs) -- We don't bother to turn non-fusible applications of concat back into concat #-}

(!!) :: [a] -> Int -> a #if defined(USE_REPORT_PRELUDE) xs !! n | n < 0 = errorWithoutStackTrace "Prelude.!!: negative index" [] !! _ = errorWithoutStackTrace "Prelude.!!: index too large" (x:) !! 0 = x (:xs) !! n = xs !! (n-1) #else

tooLarge :: Int -> a tooLarge _ = errorWithoutStackTrace (prel_list_str ++ "!!: index too large")

negIndex :: a negIndex = errorWithoutStackTrace $ prel_list_str ++ "!!: negative index"

{-# INLINABLE (!!) #-} xs !! n | n < 0 = negIndex | otherwise = foldr ([x](#local-6989586621679029988) r k -> case k of 0 -> x _ -> r (k-1)) tooLarge xs n #endif

foldr2 :: (a -> b -> c -> c) -> c -> [a] -> [b] -> c foldr2 k z = go where go [] _ys = z go _xs [] = z go (x:xs) (y:ys) = k x y (go xs ys) {-# INLINE [0] foldr2 #-}

foldr2_left :: (a -> b -> c -> d) -> d -> a -> ([b] -> c) -> [b] -> d foldr2_left _k z _x _r [] = z foldr2_left k _z x r (y:ys) = k x y (r ys)

{-# 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 #-}

{-# NOINLINE [1] zip #-} zip :: [a] -> [b] -> [(a,b)] zip [] _bs = [] zip _as [] = [] zip (a:as) (b:bs) = (a,b) : zip as bs

{-# INLINE [0] zipFB #-} zipFB :: ((a, b) -> c -> d) -> a -> b -> c -> d zipFB c = [x](#local-6989586621679030017) y r -> (x,y) [c](#local-6989586621679030016) r

{-# RULES "zip" [~1] forall xs ys. zip xs ys = build (\c n -> foldr2 (zipFB c) n xs ys) "zipList" [1] foldr2 (zipFB (:)) [] = zip #-}

zip3 :: [a] -> [b] -> [c] -> [(a,b,c)]

zip3 (a:as) (b:bs) (c:cs) = (a,b,c) : zip3 as bs cs zip3 _ _ _ = []

{-# NOINLINE [1] zipWith #-} zipWith :: (a->b->c) -> [a]->[b]->[c] zipWith f = go where go [] _ = [] go _ [] = [] go (x:xs) (y:ys) = f x y : go xs ys

{-# INLINE [0] zipWithFB #-} zipWithFB :: (a -> b -> c) -> (d -> e -> a) -> d -> e -> b -> c zipWithFB c f = [x](#local-6989586621679030034) y r -> (x [f](#local-6989586621679030033) y) [c](#local-6989586621679030032) r

{-# RULES "zipWith" [~1] forall f xs ys. zipWith f xs ys = build (\c n -> foldr2 (zipWithFB c f) n xs ys) "zipWithList" [1] forall f. foldr2 (zipWithFB (:) f) [] = zipWith f #-}

zipWith3 :: (a->b->c->d) -> [a]->[b]->[c]->[d] zipWith3 z = go where go (a:as) (b:bs) (c:cs) = z a b c : go as bs cs go _ _ _ = []

unzip :: [(a,b)] -> ([a],[b]) {-# INLINE unzip #-} unzip = foldr ((a,b) ~(as,bs) -> (a:as,b:bs)) ([],[])

unzip3 :: [(a,b,c)] -> ([a],[b],[c]) {-# INLINE unzip3 #-} unzip3 = foldr ((a,b,c) ~(as,bs,cs) -> (a:as,b:bs,c:cs)) ([],[],[])

errorEmptyList :: String -> a errorEmptyList fun = errorWithoutStackTrace (prel_list_str ++ fun ++ ": empty list")

prel_list_str :: String prel_list_str = "Prelude."