I\'m surprised I couldn\'t find an answer to this anywhere.
I\'m writing a roguelike and I\'m using the ncurses library from hackage, which is a pretty good wrapper arou
error
is supposed to be as observable as an infinite loop. You can only catch error
in IO
, which is like saying "yeah you can if you know magic". But from the really nice part of Haskell, pure code, it is unrecoverable, and thus it is strongly advised not to use in your code, only as much as you would ever use an infinite loop as an error code.
ncurses is being rude and making you do magic to correct it. I'd say unsafePerformIO
would be warranted to clean it up. Other than that, this is largely the same as Paul's answer.
import qualified Control.Exception as Exc
{-# NOINLINE unsafeCleanup #-}
unsafeCleanup :: a -> Maybe a
unsafeCleanup x = unsafePerformIO $ Exc.catch (x `seq` return (Just x)) handler
where
handler exc = return Nothing `const` (exc :: Exc.ErrorCall)
Then wrap unsafeCleanup
around any value that would evaluate to an error to turn it into a Maybe
.
This is available in the spoon package if you don't want to write it yourself (and you shouldn't -- exception code can be really tricky, especially in the presence of threads).