Panic in Haskell

In Haskell, we use exceptions for handling unexpected errors. The equivalent of Go’s panic is throwing an exception.

import System.IO.Error
import Control.Exception

main :: IO ()
main = do
    -- We'll use exceptions throughout this site to check for
    -- unexpected errors. This is the only program on the
    -- site designed to throw an exception.
    throwIO $ userError "a problem"

    -- A common use of exceptions is to abort if a function
    -- returns an error value that we don't know how to
    -- (or want to) handle. Here's an example of
    -- throwing an exception if we get an unexpected error when creating a new file.
    result <- try (openFile "/tmp/file" WriteMode) :: IO (Either IOError Handle)
    case result of
        Left err -> throwIO err
        Right _  -> return ()

Running this program will cause it to throw an exception, print an error message, and exit with a non-zero status.

When the first exception in main is thrown, the program exits without reaching the rest of the code. If you’d like to see the program try to create a temp file, comment out the first throwIO.

$ runhaskell panic.hs
panic.hs: user error (a problem)

Note that unlike some languages which use exceptions for handling of many errors, in Haskell it is idiomatic to use the Either type or similar error-indicating return values wherever possible. Exceptions are typically reserved for truly exceptional circumstances.

In Haskell, we don’t have the concept of goroutines as in Go. For concurrent programming, Haskell provides other mechanisms like lightweight threads and Software Transactional Memory (STM).