Skip to content

Commit

Permalink
Refactor: don't use reverse explicitly (haskell#6)
Browse files Browse the repository at this point in the history
I couldn't decide between the different implementations of dropWhileEnd and
takeWhileEnd from https://ghc.haskell.org/trac/ghc/ticket/9623#comment:7, so I
choose the simplest solution using two times reverse instead of foldr. See
also:
https://www.haskell.org/pipermail/libraries/2014-September/023835.html
  • Loading branch information
thomie committed Nov 1, 2014
1 parent d05cbe9 commit 881afa5
Showing 1 changed file with 27 additions and 8 deletions.
35 changes: 27 additions & 8 deletions System/FilePath/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,12 @@ getSearchPath = fmap splitSearchPath (getEnv "PATH")
-- > splitExtension "file/path.txt.bob.fred" == ("file/path.txt.bob",".fred")
-- > splitExtension "file/path.txt/" == ("file/path.txt/","")
splitExtension :: FilePath -> (String, String)
splitExtension x = case d of
splitExtension x = case nameDot of
"" -> (x,"")
(y:ys) -> (a ++ reverse ys, y : reverse c)
_ -> (dir ++ init nameDot, extSeparator : ext)
where
(a,b) = splitFileName_ x
(c,d) = break isExtSeparator $ reverse b
(dir,file) = splitFileName_ x
(nameDot,ext) = breakEnd isExtSeparator file

-- | Get the extension of a file, returns @\"\"@ for no extension, @.ext@ otherwise.
--
Expand Down Expand Up @@ -444,10 +444,10 @@ splitFileName x = (if null dir then "./" else dir, name)
-- look strange and upset simple equality properties. See
-- e.g. replaceFileName.
splitFileName_ :: FilePath -> (String, String)
splitFileName_ x = (c ++ reverse b, reverse a)
splitFileName_ x = (drv ++ dir, file)
where
(a,b) = break isPathSeparator $ reverse d
(c,d) = splitDrive x
(drv,pth) = splitDrive x
(dir,file) = breakEnd isPathSeparator pth

-- | Set the filename.
--
Expand Down Expand Up @@ -528,7 +528,7 @@ addTrailingPathSeparator x = if hasTrailingPathSeparator x then x else x ++ [pat
dropTrailingPathSeparator :: FilePath -> FilePath
dropTrailingPathSeparator x =
if hasTrailingPathSeparator x && not (isDrive x)
then let x' = reverse $ dropWhile isPathSeparator $ reverse x
then let x' = dropWhileEnd isPathSeparator x
in if null x' then [last x] else x'
else x

Expand Down Expand Up @@ -891,3 +891,22 @@ isRelativeDrive x =
-- > isAbsolute x == not (isRelative x)
isAbsolute :: FilePath -> Bool
isAbsolute = not . isRelative


-----------------------------------------------------------------------------
-- dropWhileEnd (>2) [1,2,3,4,1,2,3,4] == [1,2,3,4,1,2])
-- Note that Data.List.dropWhileEnd is only available in base >= 4.5.
dropWhileEnd :: (a -> Bool) -> [a] -> [a]
dropWhileEnd p = reverse . dropWhile p . reverse

-- takeWhileEnd (>2) [1,2,3,4,1,2,3,4] == [3,4])
takeWhileEnd :: (a -> Bool) -> [a] -> [a]
takeWhileEnd p = reverse . takeWhile p . reverse

-- spanEnd (>2) [1,2,3,4,1,2,3,4] = ([1,2,3,4,1,2], [3,4])
spanEnd :: (a -> Bool) -> [a] -> ([a], [a])
spanEnd p xs = (dropWhileEnd p xs, takeWhileEnd p xs)

-- breakEnd (< 2) [1,2,3,4,1,2,3,4] == ([1,2,3,4,1],[2,3,4])
breakEnd :: (a -> Bool) -> [a] -> ([a], [a])
breakEnd p = spanEnd (not . p)

0 comments on commit 881afa5

Please sign in to comment.