Разновидность Exception-а | Комментарий | Место кидания | Способ кидания | Место отлова | Способ отлова |
---|---|---|---|---|---|
ExceptT | Имитация исключения с помощью Either | Чистый код |
throwError | Чистый код |
catchError |
Exception | Чистый Exception | Чистый код |
throw |
IO |
catch |
IOException | "Грязный" Exception |
IO |
throwIO |
IO |
catch |
AsyncException | Асинхронное исключение, аналог сигналов в линуксе |
IO |
throwTo |
IO (поток с указанным |
catch |
throwError :: MonadError e m => e -> m a
catchError :: MonadError e m => m a -> (e -> m a) -> m a
throw :: Exception e => e -> a
throwIO :: Exception e => e -> IO a
throwTo :: Exception e => ThreadId -> e -> IO ()
catch :: Exception e => IO a -> (e -> IO a) -> IO a
- ExceptT
import Control.Monad.Except
-- An IO monad which can return String failure.
-- It is convenient to define the monad type of the combined monad,
-- especially if we combine more monad transformers.
type LengthMonad = ExceptT String IO
main = do
-- runExceptT removes the ExceptT wrapper
r <- runExceptT calculateLength
reportResult r
-- Asks user for a non-empty string and returns its length.
-- Throws an error if user enters an empty string.
calculateLength :: LengthMonad Int
calculateLength = do
-- all the IO operations have to be lifted to the IO monad in the monad stack
liftIO $ putStrLn "Please enter a non-empty string: "
s <- liftIO getLine
if null s
then throwError "The string was empty!"
else return $ length s
-- Prints result of the string length calculation.
reportResult :: Either String Int -> IO ()
reportResult (Right len) = putStrLn ("The length of the string is " ++ (show len))
reportResult (Left e) = putStrLn ("Length calculation failed with error: " ++ (show e))
- Real exceptions
data MyException = MyException deriving Show
instance Exception MyException
main = do
throwIO MyException
`catch` \MyException -> putStrLn "Caught my IO exception"
when (1 `div` 0 > 0) (putStrLn "not to happen")
`catch` \e -> putStrLn $ "Caught " <> show (e :: ArithException)
tid <- forkIO $
(threadDelay 1000000 >> putStrLn "Done")
`catch` \MyException -> putStrLn "Caught my async exception"
threadDelay 500000
throwTo tid MyException