Почему это попытка поймать пример не работает - PullRequest
3 голосов
/ 20 мая 2019

У меня есть следующий демонстрационный код от здесь :

import System.Environment  
import System.IO  
import System.IO.Error  

main = toTry `catch` 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!"

Но это дает мне ошибку:

runghc trycatch2.hs 

trycatch2.hs:5:14: error:
    Variable not in scope: catch :: IO () -> (IOError -> IO ()) -> t

Где проблема и как ее можно решить? Спасибо.

1 Ответ

2 голосов
/ 20 мая 2019

Пример в 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!"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...