Status
Accepted
Context
In a Haskell project, we often get to use and re-use the same libraries and functions. Haskell comes with a default Prelude
package with the base
library, which provides a good and sensible starting point. However, the base Prelude
also comes with a few quirks:
- Many commonly used functions or constructors are not exported by default (e.g.
bracket
,foldM
,first
,lift
,forM
,when
,SomeException
,Set
,&
...etc). - Many functions in the base Prelude are partial, like
head
orread
. - Many functions simply happens in plain
IO
, whereas applications usually try to push IO to the boundary as much as possible (for example, using mtl-style class constraints). - The interface for I/O operations in the base Prelude is
String
, which comes with quite major performance hit and often forces to convert back and forth toText
orByteString
equivalents.
All-in-all, while it does the job, the base Prelude
may not necessarily be the most convenient prelude for an active project development.
Decision
We'll use a custom prelude to help us get more productive and more importantly, to reduce the daily friction of our interactions with the base prelude. While relude
makes for a good candidate, we still chose to re-wrap it in a custom Hydra.Prelude
module to grant us the ability to add or remove a few things specifics to Hydra and Cardano in general. In particular, we will hide from relude
all the re-exports of the stm
library in favor of io-classes
which we already use pervasively and which provides (among other things) most of the same capabilities.
Consequences
- Remove uses of 'cardano-prelude' in favor of a new 'hydra-prelude' module.
- Cleaning up of imports from existing file modules.
- Happier feeling day after day from using a developer-friendly prelude.
- Stop loosing time in often re-importing the same functions over and over.
- Have an explicit point for discouraging / blessing usage of one or the other function, as well as documenting such decisions