An exception is a Haskell value whose type has an Exception instance and can represent an abnormal computational condition. Exceptions change control flow by transferring execution to a caller or handler, making them useful when interaction with files, networks, or other processes can fail. section 14.3.3 section 14.5
The core exception workflow includes:
- Define a custom exception type and give it Show and Exception instances; DeriveAnyClass can create the empty Exception instance. section 14.4
- Throw exceptions with throw or throwIO; throw has a polymorphic result, while throwIO produces an IO action. section 14.3.3
- Catch a specific exception type with catch rather than broadly catching SomeException, which may also intercept user interruptions or asynchronous control flow. section 14.4
- Use try when the failure should become an Either value, or catches when handling multiple exception types. section 14.4 section 14.5
A typed failure handler
With the DeriveAnyClass extension enabled, define data SomeFailure = SomeFailure String deriving (Show, Exception). Throw SomeFailure "Whoops" and handle it with catch using a SomeFailure pattern; unrelated exceptions from error or undefined remain uncaught. section 14.4
Listing 14.4 A safe listing function that encodes exceptions in the return value
import Control.Exception ... safeListFilesAndDirectories :: FilePath -> IO (Either IOException ([FilePath], [FilePath])) safeListFilesAndDirectories = try . listFilesAndDirectories #1
A safe file-listing function converts IOException failures into the return value IO (Either IOException ([FilePath], [FilePath])), allowing callers to handle failure explicitly. section 14.4
























