exceptiot: ExceptT, but uses IO instead of Either

[ bsd3, control, library ] [ Propose Tags ]


Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


  • No Candidates
Versions [RSS],
Change log changelog.md
Dependencies base (>=4.13 && <5), exceptions, mtl, unliftio, unliftio-core [details]
License BSD-3-Clause
Copyright 2018 Matt Parsons
Author Matt Parsons
Maintainer parsonsmatt@gmail.com
Category Control
Home page https://github.com/parsonsmatt/exceptiot#readme
Bug tracker https://github.com/parsonsmatt/exceptiot/issues
Source repo head: git clone https://github.com/parsonsmatt/exceptiot
Uploaded by parsonsmatt at 2024-05-13T16:06:27Z
Downloads 80 total (20 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2024-05-13 [all 1 reports]

Readme for exceptiot-

[back to package description]


Sometimes, it is nice to write code in MonadError to indicate that the code can throw an exception.

foo :: MonadError FooError m => Int -> m Char

We can call foo in Either FooError for a pure test, or a ExceptT FooError IO if we are writing in some monad directly. However, sometimes you can't use ExceptT. One possible reason is performance: ExceptT can add overhead. Another reason is MonadUnliftIO - ExceptT cannot have an instance for this.

You don't want to stop using MonadError, but you also can't use ExceptT anymore. What can you do?

import Control.Monad.Except.IO

main :: IO ()
main = do
    eres <- runExceptIOT (foo 3)
    case eres of
        Left FooError ->
            putStrLn "got FooError"
        Right c ->
            putChar c

You can replace ExceptT with ExceptIOT, and all exception use will switch to IO based exceptions instead of Either-based values. This allows you to use MonadUnliftIO without fear.