Dan*_*kov 6 monads haskell exception
如何在不经过Haskell的情况下使用异常IO
?
我有以下代码,用于在二元搜索树中插入元素,只需最少的比较,当元素是树的成员时不复制.我注意到,either
作为catch
和Left
作为throw
:
insert x t = either (const t) id (insert' x t Nothing)
where
insert' x E m = maybe (Right (T E x E)) (\v -> if x==v then Left E else Right (T E x E)) m
insert' x t@(T l v r) m = if x<v
then fmap (\l' -> T l' v r) (insert' x l Nothing)
else fmap (\r' -> T l v r') (insert' x r (Just v))
Run Code Online (Sandbox Code Playgroud)
因此我尝试使用Control.Monad.Error
希望使代码更简单来重写它,但是我弄得很乱.有什么建议?
这取决于你想要的例外情况.
如果您尝试从函数返回错误值(例如"未找到键"或"键已存在"),那么您应该沿着这些行使用某些内容."左"传统上用于误差值,理由是"右"是正确的结果.Error monad在这里以与"Maybe"monad相同的方式使用:当发生错误时,其余的计算都没有完成,你不必连接很多"if then else if then then ...."一起.在这种情况下,"例外"并不是特例; 您的代码必须处理它或以某种方式将其传递到下一级别.
另一方面,您可能还想捕捉不可预见的异常,例如"head []",您认为某些事情永远不会发生,但您错了.由于这些异常是不可预测的,可能是非确定性的,并且通常不适合类型系统,因此必须将它们视为IO事件.通常的模式是忽略这些异常,除了程序的最高级别,您可以尝试保存用户的工作并提供一个有用的消息,如"请报告此错误".
抛出后一种异常很容易:只需调用"错误"即可.但只能将它用于你认为不可能发生的事情; 它永远不应该是代码的正常部分.