Измените значение выхода при исключении getLine в Haskell

#haskell

#haskell

Вопрос:

Я работаю над студенческим проектом в Haskell, и у меня возникла проблема с поведением getLine. Вот код (упрощенный) :

 main :: IO()
main = do
str <- getLine
putStrLn str
  

Что я хотел бы сделать, так это, когда пользователь нажимает Ctrl D, иметь возможность exitWith (ошибка выхода 84).
getLine просто выводит ошибку и завершает работу программы (и возвращает 1)

 deBruijn: <stdin>: hGetLine: end of file
  

Как изменить это поведение? Я только хочу изменить значение выхода на 84.

Комментарии:

1. wiki.haskell.org/Handling_errors_in_Haskell

Ответ №1:

Ваша программа никогда не видит Control-D. Что он действительно видит, так это тот факт, что стандартный ввод был закрыт, в данном случае вашим терминалом в ответ на ввод элемента управления-D. Это означает, что вы хотите перехватить условие EOF перед getLine попыткой прочитать строку из закрытого файла.

 import System.IO
import System.Exit

main :: IO ()
main = do
    isClosed <- isEOF
    if isClosed 
      then exitWith (ExitFailure 84)
      else getLine >>= putStrLn
  

Комментарии:

1. Небольшое исправление: import System.IO требуется для isEOF .

Ответ №2:

Вместо ручной проверки isEof вы могли бы просто перехватить исключение ввода-вывода по мере его возникновения:

 import Control.Exception (catch)
import System.IO.Error(isEOFError)
import System.Exit

tryMain :: IO ()
tryMain = getLine >>= putStrLn

main :: IO ()
main = tryMain `catch` (e ->
  if isEOFError e
  then exitWith (ExitFailure 84)
  else exitWith (ExitFailure 99))

  

Поскольку вы, как правило, можете не исключать исключения ввода-вывода заранее, я бы рекомендовал именно этот подход.