Created
November 6, 2012 12:41
-
-
Save SKoschnicke/4024395 to your computer and use it in GitHub Desktop.
Elegant Haskell error handling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Control.Error | |
-- A made-up type for this example. | |
-- This is a bit simplified because mostly there are not only these encapsuled | |
-- types but dependent values which can only be retrieved sequentially (e.g. | |
-- reading an id from stdin, then retrieving the record for this id from a | |
-- database). | |
type MyType = (Maybe (Maybe Int)) | |
-- The goal: Return the int when it is less than 10, on other cases (greater or | |
-- equal 10, Nothing or Just Nothing) return diferent error messages. | |
-- | |
-- process Nothing ~> "error" | |
-- process (Just Nothing) ~> "error2" | |
-- process (Just (Just 20)) ~> "error3" | |
-- process (Just (Just 5)) ~> "5" | |
-- Naiive implementation. | |
-- Suffers from "creeping indentation" | |
process :: MyType -> String | |
process t = case t of | |
Nothing -> "error" | |
Just a -> case a of | |
Nothing -> "error2" | |
Just b -> if b < 10 then show b else "error3" | |
-- Using the maybe function, which makes it shorter but also harder to read. | |
process2 :: MyType -> String | |
process2 t = maybe "error" (\a -> maybe "error2" (\b -> if b < 10 then show b else "error3") a) t | |
-- Pattern matching, nicest solution so far but is not possible in more complex | |
-- cases (see comment above type definition of MyType). | |
process3 :: MyType -> String | |
process3 Nothing = "error" | |
process3 (Just Nothing) = "error2" | |
process3 (Just (Just a)) | |
| a < 10 = show a | |
| otherwise = "error3" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment