Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell - exit a program with a specified error code

In Haskell, is there a way to exit a program with a specified error code? The resources I've been reading typically point to the error function for exiting a program with an error, but it seems to always terminate the program with an error code of 1.

[martin@localhost Haskell]$ cat error.hs
main = do
    error "My English language error message"
[martin@localhost Haskell]$ ghc error.hs
[1 of 1] Compiling Main             ( error.hs, error.o )
Linking error ...
[martin@localhost Haskell]$ ./error 
error: My English language error message
[martin@localhost Haskell]$ echo $?
1
like image 805
martin Avatar asked Jun 17 '17 12:06

martin


People also ask

How do I exit a program in Haskell?

If you guessed 42 , you're right. Our Haskell process uses exitWith to exit the process with exit code 42 . Then echo $? prints the last exit code.

How do I leave Main in Haskell?

You can also quit by typing control-D at the prompt. Attempts to reload the current target set (see :load ) if any of the modules in the set, or any dependent module, has changed.

Do all programs in Haskell terminate?

The usual way of thinking about this is that every Haskell type is "lifted"--it contains ⊥. That is, Bool corresponds to {⊥, True, False} rather than just {True, False} . This represents the fact that Haskell programs are not guaranteed to terminate and can have exceptions.


2 Answers

Use exitWith from System.Exit:

main = exitWith (ExitFailure 2)

I would add some helpers for convenience:

exitWithErrorMessage :: String -> ExitCode -> IO a
exitWithErrorMessage str e = hPutStrLn stderr str >> exitWith e

exitResourceMissing :: IO a
exitResourceMissing = exitWithErrorMessage "Resource missing" (ExitFailure 2)
like image 178
Zeta Avatar answered Sep 21 '22 04:09

Zeta


An alternative that allows an error message only is die

import System.Exit

tests = ... -- some value from the program
testsResult = ... -- Bool value overall status

main :: IO ()
main = do
    if testsResult then
        print "Tests passed"
    else
        die (show tests)

The accepted answer allows setting the exit error code though, so it's closer to the exact phrasing of the question.

like image 34
Adam Burke Avatar answered Sep 21 '22 04:09

Adam Burke