On 2004 November 23 Tuesday 10:51, John Goerzen wrote: > > for pure functions, returning Either Error Result is the way to go.
> One example: I've written an FTP client library. For every operation, > there are several possible outcomes... mainly: success, low-level > network error, or server error. > > Having to pick apart an Either from every command to CD, set transfer > types, etc. would get so tedious that the code would, I think, become > spaghetti fast. The way to deal with those kinds of details is to use Either in a monad. I'm skeptical of the need for dynamic scope in conventional exception handling, so I took a shot at this problem, with satisfying results. (I'm not keen on dynamic typing for that matter, but don't know of a nice way to avoid it.) Excerpts are below. The full sample code is at http://pkturner.org/exception.tar The Haskell Main module using the FTP library is comparable to your Python example. main = runException $ do ftp("ftp.kernel.org") ( cwd "pub/linux/kernel/v2.4" `except` (\(ErrorPerm e) -> lift $ do putStrLn ("caught temp error in cwd: " ++ e) exitWith (ExitFailure 2)) ) retrbinary "RETR ChangeLog-2.4.13" (\block -> write block) quit `except` (\(ErrorPerm e) -> lift $ do putStrLn ("Permissions error " ++ e) exitWith (ExitFailure 2)) `except` (\(ErrorTemp e) -> lift $ do putStrLn ("Temporary error, please try again later" ++ e) exitWith (ExitFailure 1)) `except` (\(ErrorFTP e) -> lift $ do putStrLn ("Other FTP error" ++ e) exitWith (ExitFailure 2)) `except` (\(ErrorAll e) -> lift $ do putStrLn ("Non-FTP error" ++ e) exitWith (ExitFailure 3)) Also, the FTP module demonstrates that it's straightforward to add new classes of errors in the exception hierarchy. data ErrorPerm = ErrorPerm String deriving (Typeable) instance Hierarchical ErrorPerm where parent (ErrorPerm msg) = Parent $ ErrorFTP msg data ErrorTemp = ErrorTemp String deriving (Typeable) instance Hierarchical ErrorTemp where parent (ErrorTemp msg) = Parent $ ErrorFTP msg data ErrorFTP = ErrorFTP String deriving (Typeable) instance Hierarchical ErrorFTP where parent (ErrorFTP msg) = Parent $ ErrorAll msg type FTP = Exception IO ftp :: String -> FTP () ftp str = if take 3 str == "ftp" then lift (return ()) else raise $ ErrorPerm ("ftp " ++ str) _______________________________________________ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell