# filepather
Re-implementations of `System.FilePath` and `System.Directory` using `Kleisli` type aliases from the [kleisli](https://hackage.haskell.org/package/kleisli) package.
Each function that takes a `FilePath` as its subject argument is expressed as a `Kleisli` value, enabling composition via Functor, Applicative, Monad, and other type class instances.
## Modules
| Module | Description |
|--------|-------------|
| `System.FilePather` | Re-exports the platform-native module |
| `System.FilePather.FilePather` | Platform-native filepath and directory operations |
| `System.FilePather.FilePather.Posix` | Posix filepath operations |
| `System.FilePather.FilePather.Windows` | Windows filepath operations |
## Type aliases
```haskell
type FilePather p f a = Kleisli p FilePath f a
type FilePather' p a = FilePather p Identity a
type FilePatherA f a = FilePather (->) f a
type FilePatherA' a = FilePatherA Identity a
```
## Usage
```haskell
import System.FilePather
import Data.Kleisli (Kleisli(..))
import Data.Functor.Identity (runIdentity)
-- Pure operations return FilePatherA' (Kleisli (->) FilePath Identity a)
-- >>> runIdentity (let Kleisli f = takeExtension in f "/foo/bar.hs")
-- ".hs"
-- Effectful operations return FilePatherA IO a (Kleisli (->) FilePath IO a)
-- >>> let Kleisli f = doesFileExist in f "/tmp/example.txt"
-- False
-- Partial operations return FilePatherA Maybe a
-- >>> let Kleisli f = stripExtension ".hs" in f "/foo/bar.hs"
-- Just "/foo/bar"
-- Compose with Functor/Applicative/Monad instances
-- >>> runIdentity (let Kleisli f = fmap (++ ".bak") takeFileName in f "/tmp/notes.txt")
-- "notes.txt.bak"
```
## Building
```
cabal build
cabal test doctest
cabal bench
```