Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change exit value on getLine exception in Haskell

Tags:

haskell

I'm working on a student project in Haskell and i'm having a problem with getLine's behaviour. Here's the code (simplified) :

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

What i'd like to do is, when the user presses Ctrl+D, be able to exitWith (ExitFailure 84). getLine simply prints an error and exit the program (and returns 1)

deBruijn: <stdin>: hGetLine: end of file

How to change this behaviour ? I only want to change the exit value to 84.

like image 930
Osa Avatar asked Jan 19 '26 22:01

Osa


2 Answers

Your program never sees Control-D. What it does see is the fact that standard input has been closed, in this case by your terminal in response to Control-D being typed. This means you want to catch the EOF condition before getLine tries to read a line from a closed file.

import System.IO
import System.Exit

main :: IO ()
main = do
    isClosed <- isEOF
    if isClosed 
      then exitWith (ExitFailure 84)
      else getLine >>= putStrLn
like image 113
chepner Avatar answered Jan 23 '26 09:01

chepner


Instead of manually checking for isEof you could just catch the IO exception as it happens:

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))

As you can in general not rule out IO exceptions in advance, this is the approach I'd recommend.

like image 41
Cubic Avatar answered Jan 23 '26 07:01

Cubic