X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=Data%2FList.hs;h=bb71da5f06b9b9a4b735841f6ff2d165a39cc5bc;hb=HEAD;hp=cc166d80de94e3bb57cca73937cd1376d043a6fc;hpb=487b9d4571a847ee0273b4627aaa135c46a51b8d;p=ghc-base.git diff --git a/Data/List.hs b/Data/List.hs index cc166d8..bb71da5 100644 --- a/Data/List.hs +++ b/Data/List.hs @@ -1,4 +1,5 @@ -{-# OPTIONS_GHC -XNoImplicitPrelude #-} +{-# LANGUAGE CPP, NoImplicitPrelude, MagicHash #-} + ----------------------------------------------------------------------------- -- | -- Module : Data.List @@ -410,6 +411,8 @@ intersect = intersectBy (==) -- | The 'intersectBy' function is the non-overloaded version of 'intersect'. intersectBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] +intersectBy _ [] _ = [] +intersectBy _ _ [] = [] intersectBy eq xs ys = [x | x <- xs, any (eq x) ys] -- | The 'intersperse' function takes an element and a list and @@ -420,8 +423,16 @@ intersectBy eq xs ys = [x | x <- xs, any (eq x) ys] intersperse :: a -> [a] -> [a] intersperse _ [] = [] -intersperse _ [x] = [x] -intersperse sep (x:xs) = x : sep : intersperse sep xs +intersperse sep (x:xs) = x : prependToAll sep xs + + +-- Not exported: +-- We want to make every element in the 'intersperse'd list available +-- as soon as possible to avoid space leaks. Experiments suggested that +-- a separate top-level helper is more efficient than a local worker. +prependToAll :: a -> [a] -> [a] +prependToAll _ [] = [] +prependToAll sep (x:xs) = sep : x : prependToAll sep xs -- | 'intercalate' @xs xss@ is equivalent to @('concat' ('intersperse' xs xss))@. -- It inserts the list @xs@ in between the lists in @xss@ and concatenates the @@ -733,19 +744,24 @@ groupBy eq (x:xs) = (x:ys) : groupBy eq zs -- -- > inits "abc" == ["","a","ab","abc"] -- +-- Note that 'inits' has the following strictness property: +-- @inits _|_ = [] : _|_@ inits :: [a] -> [[a]] -inits [] = [[]] -inits (x:xs) = [[]] ++ map (x:) (inits xs) +inits xs = [] : case xs of + [] -> [] + x : xs' -> map (x :) (inits xs') -- | The 'tails' function returns all final segments of the argument, -- longest first. For example, -- -- > tails "abc" == ["abc", "bc", "c",""] -- +-- Note that 'tails' has the following strictness property: +-- @tails _|_ = _|_ : _|_@ tails :: [a] -> [[a]] -tails [] = [[]] -tails xxs@(_:xs) = xxs : tails xs - +tails xs = xs : case xs of + [] -> [] + _ : xs' -> tails xs' -- | The 'subsequences' function returns the list of all subsequences of the argument. -- @@ -1028,10 +1044,23 @@ product l = prod l 1 -- characters. The resulting strings do not contain newlines. lines :: String -> [String] lines "" = [] +#ifdef __GLASGOW_HASKELL__ +-- Somehow GHC doesn't detect the selector thunks in the below code, +-- so s' keeps a reference to the first line via the pair and we have +-- a space leak (cf. #4334). +-- So we need to make GHC see the selector thunks with a trick. +lines s = cons (case break (== '\n') s of + (l, s') -> (l, case s' of + [] -> [] + _:s'' -> lines s'')) + where + cons ~(h, t) = h : t +#else lines s = let (l, s') = break (== '\n') s in l : case s' of [] -> [] (_:s'') -> lines s'' +#endif -- | 'unlines' is an inverse operation to 'lines'. -- It joins lines, after appending a terminating newline to each.