The problem#
Compiling the Haskell package language-python (a
dependency of xcffib), I got the following warning stating
that the typeclass Error
is deprecated:
language-python/src/Language/Python/Common/ParseError.hs:25:10: warning: [-Wdeprecations]
In the use of type constructor or class ‘Error’
(imported from Control.Monad.Error.Class, but defined in Control.Monad.Trans.Error):
Deprecated: "Use Control.Monad.Trans.Except instead"
|
25 | instance Error ParseError where
| ^^^^^
I wasn't sure how to "Use Control.Monad.Trans.Except
instead", as Except
is not a drop-in replacement for Error
.
The solution#
As this StackOverflow answer recommended,
Short answer is: Replace
Error
by nothing at all
The code used throwError
, which I replaced with
throwError = lift . Left
Other than that, I just removed the import
s of Control.Monad.Error
and the typeclass instance of Error
. The full diff is
in this pull request.
The details#
Error handling in Haskell#
This article does a good job of introducing
Haskell's approach to error handling. The basic concept is that
computations that could have an error are wrapped in an
Either
where Left
values represent errors and Right
values represent normal computations. (This, of course isn't the only
way to do error handling in Haskell, but it's the most basic.)
The Error
type#
The Error
typeclass was a way to specialize that Left
type to make it
explicitly an error type and provide special constructors
for errors. As the StackOverflow answer mentioned above explains
It was found that the ability to use any error/exception type at all, polymorphically, was more useful than the somewhat hacky ability to customize conversion of string error messages.
Which is why simply getting rid of the references to Error
gets us
most of the way there.
Replacing throwError
#
language-python
referenced one function from Control.Monad.Error
:
throwError
. Effectively, it injected the error as a Left
value as
expected from the description above.
If you're using mtl
, it already defines its own
throwError
properly. If not, and you're using
Either
as your error monad, then you'll have to explicitly define it
as Left
(which is what mtl
does).
In the case of language-python
, the Either
was wrapped inside
a StateT
, so the Left
had to be lift
ed to apply
to the value inside the StateT
.
Comments
Have something to add? Post a comment by sending an email to comments@aweirdimagination.net. You may use Markdown for formatting.
There are no comments yet.