如何捕获(并忽略)对错误函数的调用?

Dav*_*aly 17 haskell exception-handling exception referential-transparency

我很惊讶我无法在任何地方找到答案.

我正在编写一个roguelike,我正在使用来自hackage的ncurses库,这是ncurses库的一个非常好的包装器.现在ncurses有这个怪癖,如果你试图写下右下角,它会这样做,然后它会尝试将光标移动到下一个角色,然后失败,因为没有地方可以将它移动到.它返回一个您只能忽略的错误值.

我的问题是haskell ncurses库编写者尽职地检查所有调用的任何错误,当有一个时,他调用:error"drawText:etc etc.".

在其他语言中,比如c或python,为了解决这个问题,你不得不忽略错误或捕获并忽略异常,但对于我的生活,我无法弄清楚如何在haskell中做到这一点.错误功能是不可恢复的吗?

我将在本地修改库,以便在必要时不检查该函数的错误,但我讨厌这样做.我也对任何可以让我在不移动光标的情况下绘制最后一个字符的解决方法持开放态度,但我不认为这是可能的.

Pau*_*aul 17

你可以使用catchfrom 来做到这一点Control.Exception.但请注意,您需要在IOmonad中执行此操作.

import qualified Control.Exception as Exc

divide :: Float -> Float -> Float
divide x 0 = error "Division by 0."
divide x y = x / y

main :: IO ()
main = Exc.catch (print $ divide 5 0) handler
    where
        handler :: Exc.ErrorCall -> IO ()
        handler _ = putStrLn $ "You divided by 0!"
Run Code Online (Sandbox Code Playgroud)


luq*_*qui 14

error应该像无限循环一样可观察.你也只能望尘莫及errorIO,这就好比说:"是的,你可以,如果你知道魔术".但是从Haskell的非常好的部分,纯代码,它是不可恢复的,因此强烈建议不要在你的代码中使用,只要你使用无限循环作为错误代码.

ncurses是粗鲁的,让你做魔术纠正它.我会说unsafePerformIO有必要清理它.除此之外,这与保罗的回答大致相同.

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)
Run Code Online (Sandbox Code Playgroud)

然后回绕unsafeCleanup任何将评估为错误的值,将其转换为Maybe.