Skip to content

Commit

Permalink
Implement 'unlines' directly (#479)
Browse files Browse the repository at this point in the history
* Implement 'unlines' directly

* Rephrase public documentation for unlines

(cherry picked from commit 5e59f1d)
  • Loading branch information
clyring authored and sjakobi committed Feb 15, 2022
1 parent bfbbf57 commit 90d98c4
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 7 deletions.
19 changes: 15 additions & 4 deletions Data/ByteString/Char8.hs
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ import Data.ByteString.Internal
import Data.Char ( isSpace )
-- See bytestring #70
import GHC.Char (eqChar)
import qualified Data.List as List (concatMap)
import qualified Data.List as List

import System.IO (Handle,stdout)
import Foreign
Expand Down Expand Up @@ -959,10 +959,21 @@ lines (BS x l) = go x l
else return [BS f i]
-}

-- | 'unlines' is an inverse operation to 'lines'. It joins lines,
-- after appending a terminating newline to each.
-- | 'unlines' joins lines, appending a terminating newline after each.
--
-- Equivalent to
-- @'concat' . Data.List.concatMap (\\x -> [x, 'singleton' \'\\n'])@.
unlines :: [ByteString] -> ByteString
unlines = concat . List.concatMap (\x -> [x, singleton '\n'])
unlines = \li -> let
totLen = List.foldl' (\acc s -> acc +! length s +! 1) 0 li
(+!) = checkedAdd "Char8.unlines"

go [] _ = pure ()
go (BS srcFP len : srcs) dest = do
unsafeWithForeignPtr srcFP $ \src -> memcpy dest src len
pokeElemOff dest len (c2w '\n')
go srcs $ dest `plusPtr` (len + 1)
in unsafeCreate totLen (go li)

-- | 'words' breaks a ByteString up into a list of words, which
-- were delimited by Chars representing white space.
Expand Down
8 changes: 5 additions & 3 deletions Data/ByteString/Lazy/Char8.hs
Original file line number Diff line number Diff line change
Expand Up @@ -885,10 +885,12 @@ lines (Chunk c0 cs0) = loop0 c0 cs0
let !c' = revChunks (B.unsafeTake n c : line)
in c' : loop0 (B.unsafeDrop (n+1) c) cs

-- | 'unlines' is an inverse operation to 'lines'. It joins lines,
-- after appending a terminating newline to each.
-- | 'unlines' joins lines, appending a terminating newline after each.
--
-- Equivalent to
-- @'concat' . Data.List.concatMap (\\x -> [x, 'singleton' \'\\n'])@.
unlines :: [ByteString] -> ByteString
unlines = concat . List.concatMap (\x -> [x, singleton '\n'])
unlines = List.foldr (\x t -> x `append` cons '\n' t) Empty

-- | 'words' breaks a ByteString up into a list of words, which
-- were delimited by Chars representing white space. And
Expand Down

0 comments on commit 90d98c4

Please sign in to comment.