No Description
Julian Ospald 809ffc7745
Add unsafeToString methods
1 year ago
cbits Merge posix-paths into hpath 3 years ago
src Add unsafeToString methods 1 year ago
test Remove redundant imports in tests 1 year ago
.ghci Basic Path type with parsers and test suite 4 years ago
.gitignore Update .gitignore 1 year ago
.travis.yml Fix travis typo 1 year ago
CHANGELOG Release 0.9.2 1 year ago
LICENSE Relicense to BSD3 3 years ago Add hackage-deps badge 1 year ago
Setup.hs First commit 4 years ago
doctests-hpath.hs Add unsafeToString methods 1 year ago
doctests-posix.hs Merge posix-paths into hpath 3 years ago
hpath.cabal Release 0.9.2 1 year ago
stack.yaml Add stack.yaml 1 year ago TRAVIS: fix 3 years ago


Gitter chat Hackage version Build Status Hackage-Deps

Support for well-typed paths in Haskell. Also provides ByteString based filepath manipulation.


The motivation came during development of hsfm which has a pretty strict File type, but lacks a strict Path type, e.g. for user input.

The library that came closest to my needs was path, but the API turned out to be oddly complicated for my use case, so I decided to fork it.

Similarly, posix-paths was exactly what I wanted for the low-level operations, but upstream seems dead, so it is forked as well and merged into this library.


  • well-typed paths
  • high-level API to file operations like recursive directory copy
  • safe filepath manipulation, never using String as filepath, but ByteString
  • still allowing sufficient control to interact with the underlying low-level calls

Note: this library was written for posix systems and it will probably not support other systems.

Differences to ‘path’

  • doesn’t attempt to fake IO-related information into the path, so whether a path points to a file or directory is up to your IO-code to decide…
  • trailing path separators will be preserved if they exist, no messing with that
  • uses safe ByteString for filepaths under the hood instead of unsafe String
  • fixes broken dirname
  • renames dirname/filename to basename/dirname to match the POSIX shell functions
  • introduces a new Path Fn for safe filename guarantees and a RelC class
  • allows pattern matching via unidirectional PatternSynonym
  • uses simple doctest for testing
  • allows ~/ as relative path, because on posix level ~ is just a regular filename that does NOT point to $HOME
  • remove TH, it sucks

Differences to ‘posix-paths’

  • uses the word8 package for save word8 literals instead of OverloadedStrings
  • hasTrailingPathSeparator and dropTrailingPathSeparator behave in the same way as their System.FilePath counterpart
  • added various functions:
    • equalFilePath
    • getSearchPath
    • hasParentDir
    • hiddenFile
    • isFileName
    • isValid
    • makeRelative
    • makeValid
    • normalise
    • splitSearchPath
    • stripExtension
  • has a custom versions of openFd which allows more control over the flags than its unix package counterpart
  • adds a getDirectoryContents' version that works on Fd

Examples in ghci

Start ghci via cabal repl:

-- enable OverloadedStrings
:set -XOverloadedStrings
-- import HPath.IO
import HPath.IO
-- parse an absolute path
abspath <- parseAbs "/home"
-- parse a relative path (e.g. user users home directory)
relpath <- parseRel "jule"
-- concatenate paths
let newpath = abspath </> relpath
-- get file type
getFileType newpath
-- return all contents of that directory
getDirsFiles newpath
-- return all contents of the parent directory
getDirsFiles (dirname newpath)