Proposal: Switch to RIO prelude
I've been using RIO for several weeks now and while still in early stages it's been proving to be more solid than the standard library. RIO is a drop-in replacement prelude specifically aimed at building user-facing apps and has a very coherent design philosophy. Some of the benefits that are relevant here include:
- Less dependency overhead (bytestring, containers, directory, filepath, text, time can all be made redundant) , and less import statements overall.
- Clear separation of total and partial functions by namespace
- tracing and very pretty logging functions out of the box, that can tee out simultaneously to multiple filehandlers.
- the
Display
typeclass and related functions which act as a human-readableShow
, to prevent overloadingShow
for that purpose (which breaks the contract withRead
) - The essential parts of
Control.Monad
,Control.Monad.Reader
andControl.Arrow
reexported by default. throwM
- A more general replacement for
Bustle/Application/Monad.hs
usingrunRIO
,HasStateRef
andunliftio
, (from my naive understanding of whatBustle/Application/Monad.hs
is doing with glib). - An emphasis on using
Text
everywhere to avoid Haskell string horror (andText
is faster thanString
)
I've made a mockup of what it might look like to just swap out prelude for rio here without taking particular advantage of any features. Some issues are:
- I had to disable gettext in the stack configuration to get it to build, how it's arranged currently doesn't seem to play well with NoImplicitPrelude for some reason. Maybe this can be reworked/upstreamed first?
- Still have to import fromEnum in normal Prelude which I've opened an issue in RIO for here
- Need to hide the
set
andon
functions in RIO because they collide with GTK functions.
For reference here are two skeleton apps that demonstrate what a typical app/cli/logging setup with RIO might look like in abstraction: 1 2
Worth exploring?