为什么可以';我不能在不同的IO中捕获异常,而不是在Haskell的()中捕获异常吗?

为什么可以';我不能在不同的IO中捕获异常,而不是在Haskell的()中捕获异常吗?,haskell,exception,exception-handling,Haskell,Exception,Exception Handling,我想捕获IO字符串函数中的所有异常。当我运行此代码时: import Control.Exception.Base handler :: SomeException -> IO String handler _ = return "Gotta catch'em all!" boom :: IO String boom = return (show (3 `div` 0)) get :: IO String get = boom `catch` handler main :: IO(

我想捕获IO字符串函数中的所有异常。当我运行此代码时:

import Control.Exception.Base

handler :: SomeException -> IO String
handler _ = return "Gotta catch'em all!"

boom :: IO String
boom = return (show (3 `div` 0))

get :: IO String
get = boom `catch` handler

main :: IO()
main = do
  x <- get
  print x
但是,该代码起作用:

import Control.Exception.Base

handler2 :: SomeException -> IO ()
handler2 _ = print "Gotta catch'em all!"

boom2 :: IO ()
boom2 = print $ show (3 `div` 0)

main :: IO()
main = do
  boom2 `catch` handler2
结果

> Gotta catch'em all!
当我将第一个示例中的boom更改为

boom = error "ERR"

异常被捕获为ok。为什么会这样?在第一个示例中,我应该如何捕获异常?

这与
()
与其他类型无关。请注意,以下内容也不适用:

boom = return $ error "ERR"
catch
对此无能为力的原因是
return
是惰性的,因此只有在尝试获取包含的值时,
catch
才会触发错误

正是由于这个原因,
异常
模块具有,这相当于
返回
,但非常严格

boom :: IO String
boom = evaluate . show $ 3`div`0
boom :: IO String
boom = evaluate . show $ 3`div`0