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)