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:
Text
andLText
,ByteString
andLByteString
, 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
Text
overString
- Lifts
IO
functions toMonadIO
More correct
- No partial functions
head
works onNonEmpty a
readMaybe
instead ofread
- etc.
unliftio
: Extended standard library
More convenient
- Re-exports types and functions from
base
,async
,bytestring
,directory
,process
,stm
, etc. - Lifts
IO
functions toMonadIO
- Lifts
IO
functions takingIO
arguments toMonadUnliftIO
base
:withFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r
unliftio
: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
MonadUnliftIO
type 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
Conc
type, a more efficient alternative toasync
'sConcurrently
that 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
Fold
andUnfold
types - inspired by thefoldl
library - for producing and consuming streams, respectively - Streams can be produced, transformed, and consumed concurrently (you can completely replace
async
withstreamly
, more info)
optics
: Alternative lens
- Abstract interface makes for much nicer type errors and easier to read documentation
- Comes with
generic-lens
-styleOverloadedLabels
functionality 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 @YourType
ortryInto @YourType
)