这里没有争论,Haskell中有各种各样的机制来处理错误并妥善处理它们.错误monad,Either,Maybe,exception等.
那么为什么在Haskell中编写其他语言中容易出现异常的代码感觉更直接呢?
假设我想编写一个命令行工具来处理在命令行上传递的文件.我想:
所以一个非常直接的文件处理工具.
在Haskell中,我将使用Maybe和Either将这些代码包装在monad的某些组合中,并根据需要翻译和传播错误.最后,它都进入IO monad,我可以将状态输出给用户.
在另一种语言中,我只是抛出异常并捕获到适当的位置.直截了当.我不会花太多时间在认知困境中试图解开我需要的机制组合.
我只是接近这个错误,还是这种感觉有一些实质内容?
编辑:好的,我得到的反馈告诉我,这感觉更难,但事实并非如此.所以这是一个痛点.在Haskell中,我正在处理monad堆栈,如果我必须处理错误,我会在这个monad堆栈中添加另一个层.我不知道有多少电梯和其他语法垃圾只是为了使代码编译而添加,但增加了零语义含义.没有人觉得这增加了复杂性?
我希望能够确保函数在接收到无效值时会抛出错误.例如,假设我有一个只返回正数的函数pos:
pos :: Int -> Int
pos x
| x >= 0 = x
| otherwise = error "Invalid Input"
Run Code Online (Sandbox Code Playgroud)
这是一个简单的例子,但我希望你能得到这个想法.
我希望能够编写一个期望出现错误的测试用例并将其视为通过测试.例如:
tests = [pos 1 == 1, assertError pos (-1), pos 2 == 2, assertError pos (-2)]
runTests = all (== True) tests
Run Code Online (Sandbox Code Playgroud)
[我的解决方案]
这是我最终根据@ hammar的评论进行的.
instance Eq ErrorCall where
x == y = (show x) == (show y)
assertException :: (Exception e, Eq e) => e -> IO a -> IO ()
assertException ex action =
handleJust isWanted …Run Code Online (Sandbox Code Playgroud)