module GHC.List ( map, (++), filter, concat, head, last, tail, init, null, length, (!!), 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, concatMap, zip, zip3, zipWith, zipWith3, unzip, unzip3, errorEmptyList, #ifndef USE_REPORT_PRELUDE takeUInt_append #endif ) where import Data.Maybe import GHC.Base infixl 9 !! infix 4 `elem`, `notElem`\end{code} %********************************************************* %* * \subsection{List-manipulation functions} %* * %********************************************************* \begin{code}
head :: [a] -> a head (x:_) = x head [] = badHead badHead :: a badHead = errorEmptyList "head" tail :: [a] -> [a] tail (_:xs) = xs tail [] = errorEmptyList "tail" last :: [a] -> a #ifdef USE_REPORT_PRELUDE last [x] = x last (_:xs) = last xs last [] = errorEmptyList "last" #else last [] = errorEmptyList "last" last (x:xs) = last' x xs where last' y [] = y last' _ (y:ys) = last' y ys #endif init :: [a] -> [a] #ifdef 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 length :: [a] -> Int length l = len l 0# where len :: [a] -> Int# -> Int len [] a# = I# a# len (_:xs) a# = len xs (a# +# 1#) filter :: (a -> Bool) -> [a] -> [a] filter _pred [] = [] filter pred (x:xs) | pred x = x : filter pred xs | otherwise = filter pred xs filterFB :: (a -> b -> b) -> (a -> Bool) -> a -> b -> b filterFB c p x r | p x = x `c` r | otherwise = r foldl :: (a -> b -> a) -> a -> [b] -> a foldl f z0 xs0 = lgo z0 xs0 where lgo z [] = z lgo z (x:xs) = lgo (f z x) xs scanl :: (a -> b -> a) -> a -> [b] -> [a] scanl f q ls = q : (case ls of [] -> [] x:xs -> scanl f (f q x) xs) scanl1 :: (a -> a -> a) -> [a] -> [a] scanl1 f (x:xs) = scanl f x xs scanl1 _ [] = [] foldr1 :: (a -> a -> a) -> [a] -> a foldr1 _ [x] = x foldr1 f (x:xs) = f x (foldr1 f xs) foldr1 _ [] = errorEmptyList "foldr1" 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 scanr1 :: (a -> a -> a) -> [a] -> [a] scanr1 _ [] = [] scanr1 _ [x] = [x] scanr1 f (x:xs) = f x q : qs where qs@(q:_) = scanr1 f xs iterate :: (a -> a) -> a -> [a] iterate f x = x : iterate f (f x) iterateFB :: (a -> b -> b) -> (a -> a) -> a -> b iterateFB c f x = x `c` iterateFB c f (f x) repeat :: a -> [a] repeat x = xs where xs = x : xs repeatFB :: (a -> b -> b) -> a -> b repeatFB c x = xs where xs = x `c` xs replicate :: Int -> a -> [a] replicate n x = take n (repeat x) cycle :: [a] -> [a] cycle [] = error "Prelude.cycle: empty list" cycle xs = xs' where xs' = xs ++ xs' 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 :: Int -> [a] -> [a] drop :: Int -> [a] -> [a] splitAt :: Int -> [a] -> ([a],[a]) #ifdef USE_REPORT_PRELUDE take n _ | n <= 0 = [] take _ [] = [] take n (x:xs) = x : take (n1) xs drop n xs | n <= 0 = xs drop _ [] = [] drop n (_:xs) = drop (n1) xs splitAt n xs = (take n xs, drop n xs) #else /* hack away */ takeFoldr :: Int -> [a] -> [a] takeFoldr (I# n#) xs = build (\c nil -> if n# <=# 0# then nil else foldr (takeFB c nil) (takeConst nil) xs n#) takeConst :: a -> Int# -> a takeConst x _ = x takeFB :: (a -> b -> b) -> b -> a -> (Int# -> b) -> Int# -> b takeFB c n x xs m | m <=# 1# = x `c` n | otherwise = x `c` xs (m -# 1#) take (I# n#) xs = takeUInt n# xs takeUInt :: Int# -> [b] -> [b] takeUInt n xs | n >=# 0# = take_unsafe_UInt n xs | otherwise = [] take_unsafe_UInt :: Int# -> [b] -> [b] take_unsafe_UInt 0# _ = [] take_unsafe_UInt m ls = case ls of [] -> [] (x:xs) -> x : take_unsafe_UInt (m -# 1#) xs takeUInt_append :: Int# -> [b] -> [b] -> [b] takeUInt_append n xs rs | n >=# 0# = take_unsafe_UInt_append n xs rs | otherwise = [] take_unsafe_UInt_append :: Int# -> [b] -> [b] -> [b] take_unsafe_UInt_append 0# _ rs = rs take_unsafe_UInt_append m ls rs = case ls of [] -> rs (x:xs) -> x : take_unsafe_UInt_append (m -# 1#) xs rs drop (I# n#) ls | n# <# 0# = ls | otherwise = drop# n# ls where drop# :: Int# -> [a] -> [a] drop# 0# xs = xs drop# _ xs@[] = xs drop# m# (_:xs) = drop# (m# -# 1#) xs splitAt (I# n#) ls | n# <# 0# = ([], ls) | otherwise = splitAt# n# ls where splitAt# :: Int# -> [a] -> ([a], [a]) splitAt# 0# xs = ([], xs) splitAt# _ xs@[] = (xs, 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]) #ifdef 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] #ifdef 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 or :: [Bool] -> Bool #ifdef USE_REPORT_PRELUDE and = foldr (&&) True or = foldr (||) False #else and [] = True and (x:xs) = x && and xs or [] = False or (x:xs) = x || or xs #endif any :: (a -> Bool) -> [a] -> Bool all :: (a -> Bool) -> [a] -> Bool #ifdef USE_REPORT_PRELUDE any p = or . map p all p = and . map p #else any _ [] = False any p (x:xs) = p x || any p xs all _ [] = True all p (x:xs) = p x && all p xs #endif elem :: (Eq a) => a -> [a] -> Bool notElem :: (Eq a) => a -> [a] -> Bool #ifdef USE_REPORT_PRELUDE elem x = any (== x) notElem x = all (/= x) #else elem _ [] = False elem x (y:ys) = x==y || elem x ys notElem _ [] = True notElem x (y:ys)= x /= y && notElem x ys #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) [] concat :: [[a]] -> [a] concat = foldr (++) []\end{code} \begin{code}
(!!) :: [a] -> Int -> a #ifdef USE_REPORT_PRELUDE xs !! n | n < 0 = error "Prelude.!!: negative index" [] !! _ = error "Prelude.!!: index too large" (x:_) !! 0 = x (_:xs) !! n = xs !! (n1) #else xs !! (I# n0) | n0 <# 0# = error "Prelude.(!!): negative index\n" | otherwise = sub xs n0 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} %********************************************************* %* * \subsection{The zip family} %* * %********************************************************* \begin{code}
foldr2 :: (a -> b -> c -> c) -> c -> [a] -> [b] -> c 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 :: (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) foldr2_right :: (a -> b -> c -> d) -> d -> b -> ([a] -> c) -> [a] -> d foldr2_right _k z _y _r [] = z foldr2_right k _z y r (x:xs) = k x y (r xs)\end{code} The foldr2/right rule isn't exactly right, because it changes the strictness of foldr2 (and thereby zip) E.g. main = print (null (zip nonobviousNil (build undefined))) where nonobviousNil = f 3 f n = if n == 0 then [] else f (n-1) I'm going to leave it though. Zips for larger tuples are in the List module. \begin{code}
zip :: [a] -> [b] -> [(a,b)] zip (a:as) (b:bs) = (a,b) : zip as bs zip _ _ = [] zipFB :: ((a, b) -> c -> d) -> a -> b -> c -> d zipFB c = \x y r -> (x,y) `c` r\end{code} \begin{code}
zip3 :: [a] -> [b] -> [c] -> [(a,b,c)] 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. \begin{code}
zipWith :: (a->b->c) -> [a]->[b]->[c] zipWith f (a:as) (b:bs) = f a b : zipWith f as bs zipWith _ _ _ = [] zipWithFB :: (a -> b -> c) -> (d -> e -> a) -> d -> e -> b -> c zipWithFB c f = \x y r -> (x `f` y) `c` r\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 :: [(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)) ([],[],[])\end{code} %********************************************************* %* * \subsection{Error code} %* * %********************************************************* Common up near identical calls to `error' to reduce the number constant strings created when compiled: \begin{code}
errorEmptyList :: String -> a errorEmptyList fun = error (prel_list_str ++ fun ++ ": empty list") prel_list_str :: String prel_list_str = "Prelude."\end{code}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4