I started reformatting a small, old codebase this morning that used Control.Monad.Error which is now deprecated and the docs for that point to Control.Monad.Except. Control.Monad.Freer.Error also came up in searching through hackage for different error handling options.
So, I’m just wondering if anyone might share their opinions on situations where each of those might be preferable?
I think if I get time I will try to reformat using both as a learning exercise but am only at the outset.
If the rest of the code uses MTL style (constraints like MonadState
, MonadReader
, …) or transformers (explicitly nested stacks like StateT ...
, ReaderT ...
) then it’s unlikely that you have any choice but to use Control.Monad.Except
.
On the other hand, if the current structure of the code allows you freedom over what effect system you choose then I recommend a modern IO-based effect system, either Bluefin or effectful.
If it used Control.Monad.Error
, there is a pretty good chance you’ll be able to use Control.Monad.Except
as a (mostly) drop-in replacement.
Control.Monad.Freer.Error
is part of the effect system library freer-simple. The idea is essentially that you can seamlessly compose different effects (~monads) together without worrying about the order like with monad transformers and swap out the concrete implementation if you need to (e.g. for tests).
If you don’t plan on migrating the entire codebase to an effect system, you should probably stick to Control.Monad.Except (which, to be clear, is a perfectly fine choice)
If you do want to use an effect system, keep in mind that freer-simple is relatively old, somewhat bare bones and (because it’s implemented through freer monads) quite slow.
You should probably use effectful instead, which is much more modern, better integrated with the haskell ecosystem and significantly more efficient.
Question - is there a way to easily navigate from https://hackage.haskell.org/package/bluefin to https://hackage.haskell.org/package/bluefin-0.0.4.3/docs/Bluefin.html that I am missing? If there is I’m a goose and please ignore the next paragraph.
FWIW as feedback, I nearly entirely committed to effectful purely because it has the readme as part of the page one encounters when searching on Hackage so is initially more easily navigable. But I’ve found the overview page of bluefin I was after and am having a read now.
Do you not see the list of Modules right there on the Hackage package page?
The top Bluefin module is literally the first one.
Having said that I do dislike when packages which don’t include a README file (or almost worse the readme file is a link the github repo/readme).
Goose status confirmed. Was clicking everything but the one I needed!
Is there any particular reason you don’t also mention Bluefin here? I’m just asking so I can know what to change/improve so that Bluefin is recommended by default alongside effectful.
Oh, I just chose effectful because it’s the best direct replacement for freer-simple with the same API and almost no downsides. (you could probably move some imports around, declare a few type synonyms and immediately get 90% of code that uses freer-simple to work under effectful).
Bluefin is absolutely a valid choice as well! It just has a slightly different API.
I would also consider polysemy perfectly acceptable if you want the additional flexibility in effect handlers and/or need a NonDet
effect, although if you don’t, keep in mind that effectful and bluefin are much faster