Skip to content

Instantly share code, notes, and snippets.

@SKoschnicke
Created November 6, 2012 12:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SKoschnicke/4024395 to your computer and use it in GitHub Desktop.
Save SKoschnicke/4024395 to your computer and use it in GitHub Desktop.
Elegant Haskell error handling
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