我在Haskell中有一个函数,它通过迭代工作,每当达到3000次迭代时就会抛出错误。
最近我发现了Control.Exception,它允许定义、抛出和捕获异常。我想多了解一些。
我觉得这很难理解(对于像我这样的Haskell新手来说)。所以我需要一些帮助。
当达到3000次迭代时,我想抛出我的自定义异常,并显示类似“Exception:3000次迭代”。我在文档中找到了displayException
,这是要走的路吗?
到目前为止,这是我所做的(这仍然是一个测试阶段):
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExistentialQuantification #-}
import Control.Exception (Exception)
-- for testing purpose
data MyException = ThisException | ThatException
deriving Show
instance Exception MyException
data ReachedMax = forall e.Exception e => ReachedMax e
instance Show ReachedMax where
showsPrec :: Int -> ReachedMax -> ShowS
showsPrec p (ReachedMax e) = showsPrec p e
有时(经常)我应该说我盲目地复制HLS的建议。我走对了吗?我可以继续使用ReachedMax
构造函数吗?
后台
正如你们中的一些人所知道的,这些天我在用Haskell做2D图像。其中一个依赖于具有此功能的包,该功能可实现3000次迭代。我想抓住这些幽灵。
1条答案
按热度按时间smdnsysy1#
当GHC运行时捕获异常并通过消息停止程序时:
"blah blah blah"
字符串由show
从Show
类型类生成。(为此,Exception
中的displayException
方法将被忽略。所以,你需要定义一个自定义的异常类型:
给予一个
Show
示例,用于显示所需的错误消息:并使其成为
Exception
类的示例:然后,当你在纯代码中
throw
这个异常时,当相关的表达式被求值时,程序将被你的自定义异常终止。例如,如果你有一个函数测试Collatz猜想的整数,并返回所需的迭代次数(但如果迭代次数超过100,则抛出自定义异常):
在GHCi中运行几个测试,你应该看到所需的行为:
如果你想捕获这个异常,你需要在IO monad中强制计算纯代码,并使用
catch
或try
来捕获所需的异常:在这两种情况下,捕获函数都需要用正确的
Exception
类型示例化,并且该类型确定捕获哪些异常。你只需要以下形式的existential exceptions:
如果要创建异常的层次结构,以便可以捕获包含多个异常类型的层次结构的分支,而不是捕获特定的异常类型,请使用。
完整代码示例: