module Text.PortableLines
( lines
) where
import Prelude hiding (lines)
import qualified Prelude as P
-- | Like the 'P.lines' function from Prelude, but treat the @\"\\r\\n\"@ and
-- @\"\\r\"@ sequences as newlines too, not just @\"\\n\"@.
lines :: String -> [String]
lines [] = []
lines str = let (a, str') = breakNewline str
in a : lines str'
breakNewline :: String -> (String, String)
breakNewline [] = ([], [])
breakNewline (x : xs) =
case x of
'\n' -> ([], xs)
'\r' -> ([], case xs of
('\n' : xs') -> xs'
_ -> xs)
-- The reason for the weird case expression instead of just a
-- ('\r' : '\n' : s) pattern is for better laziness.
-- Otherwise, lines ("hello\r" ++ undefined) would fail to
-- completely yield the first line. If we see a '\r', we know
-- the line has ended, so don't force the next character
-- immediately.
_ -> let (line, rest) = breakNewline xs
in (x : line, rest)