相关疑难解决方法(0)

Haskell处理错误处理

这里没有争论,Haskell中有各种各样的机制来处理错误并妥善处理它们.错误monad,Either,Maybe,exception等.

那么为什么在Haskell中编写其他语言中容易出现异常的代码感觉更直接呢?

假设我想编写一个命令行工具来处理在命令行上传递的文件.我想:

  • 验证是否提供了文件名
  • 验证文件可用且可读
  • 验证文件具有有效标头
  • 创建输出文件夹并验证输出文件是否可写
  • 处理文件,解析错误时出错,不变错误等.
  • 输出文件,写入错误错误,磁盘已满等.

所以一个非常直接的文件处理工具.

在Haskell中,我将使用Maybe和Either将这些代码包装在monad的某些组合中,并根据需要翻译和传播错误.最后,它都进入IO monad,我可以将状态输出给用户.

在另一种语言中,我只是抛出异常并捕获到适当的位置.直截了当.我不会花太多时间在认知困境中试图解开我需要的机制组合.

我只是接近这个错误,还是这种感觉有一些实质内容?

编辑:好的,我得到的反馈告诉我,这感觉更难,但事实并非如此.所以这是一个痛点.在Haskell中,我正在处理monad堆栈,如果我必须处理错误,我会在这个monad堆栈中添加另一个层.我不知道有多少电梯和其他语法垃圾只是为了使代码编译而添加,但增加了零语义含义.没有人觉得这增加了复杂性?

haskell exception

40
推荐指数
3
解决办法
2868
查看次数

如何在Haskell中测试错误?

我希望能够确保函数在接收到无效值时会抛出错误.例如,假设我有一个只返回正数的函数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)

testing error-handling haskell unit-testing hunit

8
推荐指数
1
解决办法
3185
查看次数