代码之家  ›  专栏  ›  技术社区  ›  David McHealy

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

  •  16
  • David McHealy  · 技术社区  · 14 年前

    我很惊讶在任何地方都找不到答案。

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

    我的问题是,haskell ncurses库编写器尽职尽责地检查所有调用上的错误,当有错误时,他调用:error“drawText:etc.”。

    在其他语言中,比如c或python,为了解决这个问题,你不得不忽略错误或捕获并忽略异常,但在我的一生中,我不知道如何在haskell中做到这一点。错误函数是否不可恢复?

    如果必须的话,我将在本地修改库,以不检查该函数是否有错误,但我讨厌这样做。我也愿意接受任何可以让我在不移动光标的情况下绘制最后一个字符的解决方案,但我认为这是不可能的。

    2 回复  |  直到 14 年前
        1
  •  14
  •   luqui    6 年前

    error 应该像一个无限循环一样可以观察到。你只能抓住 错误 在里面 IO ,这是l####标题####ike说的“是的,如果你知道魔法,你可以”。但是从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)
    

    然后包装 unsafeCleanup 将计算为错误的任何值周围的值转换为 Maybe .

    这在 spoon 如果您不想自己编写(而且不应该——异常代码可能非常棘手,特别是在线程存在的情况下)。

        2
  •  17
  •   Paul    14 年前

    你可以用 catch Control.Exception . 但是,请注意,您需要在 IO 蒙纳德要这么做。

    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!"
    
    推荐文章