Пример в Learn You Haskell для Большого блага является устаревшим , catch :: Exception e => IO a -> (e -> IO a) -> IO a
функция является частью Control.Exception
.
System.IO.Error
однако все еще имеет функцию захвата, которая здесь применима: catchIOError :: IO a -> (IOError -> IO a) -> IO a
, но, как сказано в документации :
Функция catchIOError
устанавливает обработчик, который получает любые IOException
, поднятые в действии, защищенном catchIOError
. IOException перехватывается самым последним обработчиком, установленным одной из функций обработки исключений. Эти обработчики не являются выборочными: все IOExceptions
перехвачены.
(...)
Не-I / O исключения не перехватываются этим вариантом; чтобы перехватить все исключения, используйте catch
из Control.Exception
.
Таким образом, вы можете устранить проблему с помощью catchIOError
(поскольку вы имеете дело с IOError
, но, как указано в документации, это охватывает только ограниченный набор исключений), или вы можете импортировать catch
от Control.Exception
:
<b>import Control.Exception(catch)</b>
import System.Environment
import System.IO
import System.IO.Error
main :: IO ()
main = toTry `<b>catch</b>` handler
toTry :: IO ()
toTry = do (fileName:_) <- getArgs
contents <- readFile fileName
putStrLn $ "The file has " ++ show (length (lines contents)) ++ " lines!"
handler :: IOError -> IO ()
handler e = putStrLn "Whoops, had some trouble!"