public
Created

Elegant Haskell error handling

  • Download Gist
error.hs
Haskell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
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"

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.