X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=GHC%2FList.lhs;h=e265733743d3e1f64acd82d46c96d92d5d2b4b4c;hb=4d648b3b6d630bf08226f40d2cddc3584239fc87;hp=02119655722cd3b329beda5826e2fdf42d1578d8;hpb=aaf764b3ad8b1816d68b5f27299eac125f08e1a5;p=ghc-base.git diff --git a/GHC/List.lhs b/GHC/List.lhs index 0211965..e265733 100644 --- a/GHC/List.lhs +++ b/GHC/List.lhs @@ -14,6 +14,7 @@ -- ----------------------------------------------------------------------------- +-- #hide module GHC.List ( -- [] (..), -- Not Haskell 98; built in syntax @@ -37,7 +38,7 @@ module GHC.List ( ) where import {-# SOURCE #-} GHC.Err ( error ) -import Data.Tuple +import Data.Tuple() -- Instances import Data.Maybe import GHC.Base @@ -62,7 +63,7 @@ badHead = errorEmptyList "head" -- 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) @@ -253,6 +254,7 @@ repeatFB c x = xs where xs = x `c` xs -- 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) @@ -265,7 +267,12 @@ 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@. +-- longest prefix (possibly empty) of @xs@ of elements that satisfy @p@: +-- +-- > takeWhile (< 3) [1,2,3,4,1,2,3,4] == [1,2] +-- > takeWhile (< 9) [1,2,3] == [1,2,3] +-- > takeWhile (< 0) [1,2,3] == [] +-- takeWhile :: (a -> Bool) -> [a] -> [a] takeWhile _ [] = [] @@ -273,7 +280,12 @@ takeWhile p (x:xs) | p x = x : takeWhile p xs | otherwise = [] --- | 'dropWhile' @p xs@ returns the suffix remaining after 'takeWhile' @p xs@. +-- | 'dropWhile' @p xs@ returns the suffix remaining after 'takeWhile' @p xs@: +-- +-- > dropWhile (< 3) [1,2,3,4,5,1,2,3] == [3,4,5,1,2,3] +-- > dropWhile (< 9) [1,2,3] == [] +-- > dropWhile (< 0) [1,2,3] == [1,2,3] +-- dropWhile :: (a -> Bool) -> [a] -> [a] dropWhile _ [] = [] @@ -282,19 +294,46 @@ dropWhile p xs@(x: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@. +-- of length @n@, or @xs@ itself if @n > 'length' xs@: +-- +-- > take 5 "Hello World!" == "Hello" +-- > take 3 [1,2,3,4,5] == [1,2,3] +-- > take 3 [1,2] == [1,2] +-- > take 3 [] == [] +-- > take (-1) [1,2] == [] +-- > take 0 [1,2] == [] +-- -- It is an instance of the more general 'Data.List.genericTake', -- in which @n@ may be of any integral type. take :: Int -> [a] -> [a] -- | 'drop' @n xs@ returns the suffix of @xs@ --- after the first @n@ elements, or @[]@ if @n > 'length' xs@. +-- after the first @n@ elements, or @[]@ if @n > 'length' xs@: +-- +-- > drop 6 "Hello World!" == "World!" +-- > drop 3 [1,2,3,4,5] == [4,5] +-- > drop 3 [1,2] == [] +-- > drop 3 [] == [] +-- > drop (-1) [1,2] == [1,2] +-- > drop 0 [1,2] == [1,2] +-- -- It is an instance of the more general 'Data.List.genericDrop', -- in which @n@ may be of any integral type. drop :: Int -> [a] -> [a] --- | 'splitAt' @n xs@ is equivalent to @('take' n xs, 'drop' n xs)@. --- It is an instance of the more general 'Data.List.genericSplitAt', +-- | 'splitAt' @n xs@ returns a tuple where first element is @xs@ prefix of +-- length @n@ and second element is the remainder of the list: +-- +-- > splitAt 6 "Hello World!" == ("Hello ","World!") +-- > splitAt 3 [1,2,3,4,5] == ([1,2,3],[4,5]) +-- > splitAt 1 [1,2,3] == ([1],[2,3]) +-- > splitAt 3 [1,2,3] == ([1,2,3],[]) +-- > splitAt 4 [1,2,3] == ([1,2,3],[]) +-- > splitAt 0 [1,2,3] == ([],[1,2,3]) +-- > splitAt (-1) [1,2,3] == ([],[1,2,3]) +-- +-- It is equivalent to @('take' n xs, 'drop' n xs)@. +-- 'splitAt' is an instance of the more general 'Data.List.genericSplitAt', -- in which @n@ may be of any integral type. splitAt :: Int -> [a] -> ([a],[a]) @@ -310,6 +349,23 @@ drop n (_:xs) = drop (n-1) xs 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 @@ -362,7 +418,15 @@ splitAt (I# n#) ls #endif /* USE_REPORT_PRELUDE */ --- | 'span' @p xs@ is equivalent to @('takeWhile' p xs, 'dropWhile' p xs)@ +-- | 'span', applied to a predicate @p@ and a list @xs@, returns a tuple where +-- first element is longest prefix (possibly empty) of @xs@ of elements that +-- satisfy @p@ and second element is the remainder of the list: +-- +-- > span (< 3) [1,2,3,4,1,2,3,4] == ([1,2],[3,4,1,2,3,4]) +-- > span (< 9) [1,2,3] == ([1,2,3],[]) +-- > span (< 0) [1,2,3] == ([],[1,2,3]) +-- +-- 'span' @p xs@ is equivalent to @('takeWhile' p xs, 'dropWhile' p xs)@ span :: (a -> Bool) -> [a] -> ([a],[a]) span _ xs@[] = (xs, xs) @@ -370,7 +434,15 @@ span p xs@(x:xs') | p x = let (ys,zs) = span p xs' in (x:ys,zs) | otherwise = ([],xs) --- | 'break' @p@ is equivalent to @'span' ('not' . p)@. +-- | 'break', applied to a predicate @p@ and a list @xs@, returns a tuple where +-- first element is longest prefix (possibly empty) of @xs@ of elements that +-- /do not satisfy/ @p@ and second element is the remainder of the list: +-- +-- > break (> 3) [1,2,3,4,1,2,3,4] == ([1,2,3],[4,1,2,3,4]) +-- > break (< 9) [1,2,3] == ([],[1,2,3]) +-- > break (> 9) [1,2,3] == ([1,2,3],[]) +-- +-- 'break' @p@ is equivalent to @'span' ('not' . p)@. break :: (a -> Bool) -> [a] -> ([a],[a]) #ifdef USE_REPORT_PRELUDE