Haskell Libraries I Love
I just wanted to share some of my favorite Haskell libraries, and why I love them. Most of my projects use most of these libraries.
relude: Alternative Prelude
More convenient
- Re-exports common types, type classes, and functions from
base,containers,text,bytestring, etc.- Types:
TextandLText,ByteStringandLByteString, etc. - Type classes:
Alternative,MonadIO,Generic, etc. - Functions:
traverse_,when,fromMaybe, etc.
- Types:
- Provides extra utility type classes and functions
- Type classes:
One,ToText,ToString,ConvertUtf8, etc. - Functions:
whenM,whenJust, etc.
- Type classes:
- Prefers
TextoverString - Lifts
IOfunctions toMonadIO
More correct
- No partial functions
headworks onNonEmpty areadMaybeinstead ofread- etc.
unliftio: Extended standard library
More convenient
- Re-exports types and functions from
base,async,bytestring,directory,process,stm, etc. - Lifts
IOfunctions toMonadIO - Lifts
IOfunctions takingIOarguments toMonadUnliftIObase:withFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO runliftio:withFile :: MonadUnliftIO m => FilePath -> IOMode -> (Handle -> m a) -> m a
- Consistent module naming scheme (
UnliftIO.{Async,Directory,Process,STM,etc.})
More correct
- Monads implementing the
MonadUnliftIOtype class don't discard monadic state (more info) - Doesn't catch async exceptions (more info)
- Uses uninterruptible masking for
bracket's cleanup handler (more info) - Doesn't re-export unsafe functions like
readFile(more info)
More performant
- Provides the
Conctype, a more efficient alternative toasync'sConcurrentlythat forks fewer threads
streamly: Streaming and concurrency
- Extremely efficient, highly optimized internals
- Straightforward/boring API, no confusing type-level programming or poor type inference
- Represents a stream as data which is transformed using combinators, instead of composing a pipeline of stream transformation functions
- Provides composable
FoldandUnfoldtypes - inspired by thefoldllibrary - for producing and consuming streams, respectively - Streams can be produced, transformed, and consumed concurrently (you can completely replace
asyncwithstreamly, more info)
optics: Alternative lens
- Abstract interface makes for much nicer type errors and easier to read documentation
- Comes with
generic-lens-styleOverloadedLabelsfunctionality out of the box - Smaller dependency footprint, faster compile time
witch: Rust's From and TryFrom traits in Haskell
- The convenience of
relude'sToText/ToString/ConvertUtf8/etc. conversion type classes, applied to all types - Very simple API (just call
into @YourTypeortryInto @YourType)