为什么我不能在Haskell中的不同IO中捕获异常而不是()?

rad*_*row 2 haskell exception-handling exception

我想捕获IO String函数中的所有异常.当我运行此代码时:

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
Run Code Online (Sandbox Code Playgroud)

我明白了

exctest: divide by zero
Run Code Online (Sandbox Code Playgroud)

但是这段代码有效:

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
Run Code Online (Sandbox Code Playgroud)

结果

> Gotta catch'em all!
Run Code Online (Sandbox Code Playgroud)

当我在第一个例子中改变繁荣时

boom = error "ERR"
Run Code Online (Sandbox Code Playgroud)

抓住了例外.为什么它会这样?在第一个例子中我该怎么做才能捕获异常?

lef*_*out 8

()与其他类型无关.请注意,以下内容也没有捕获:

boom = return $ error "ERR"
Run Code Online (Sandbox Code Playgroud)

原因是catch没有做任何事情return就是懒惰,因此错误实际上并没有被触发catch,只有当你试图获得所包含的值时.

正是由于这个原因,Exception模块已经评估,这相当于return但严格.

boom :: IO String
boom = evaluate . show $ 3`div`0
Run Code Online (Sandbox Code Playgroud)