import Control.Monad ((>=>))
data Error =
TooSmall
| TooBig
| Even
| NotDivisibleByThree
deriving Show
inBounds x
| x < 0 = Left TooSmall
| x > 10 = Left TooBig
| otherwise = Right x
isOdd x
| even x = Left Even
| otherwise = Right x
divisibleByThree x
| x `mod` 3 /= 0 = Left NotDivisibleByThree
| otherwise = Right x
validate = inBounds >=> isOdd >=> divisibleByThree
-- *Main> mapM_ (print . validate) [-1,0..11]
-- Left TooSmall
-- Left Even
-- Left NotDivisibleByThree
-- Left Even
-- Right 3
-- Left Even
-- Left NotDivisibleByThree
-- Left Even
-- Left NotDivisibleByThree
-- Left Even
-- Right 9
-- Left Even
-- Left TooBig
As a plus, it also works on generic integer types. /troll ;)
My beef with Go’s error handling is that it’s too simple, and not consistent. For one, many places in the standard library make it impossible to distinguish between the types of errors that occur.
Take for instance, the errors returned by the http library. More often than not the only way to distinguish what happened (and handle it differently) is to look at the string representation of the error, and they are almost never consistent!
Some of these errors are saved off via errors.New() so you can actually compare a known error against them, or exist as a ProtocolErrorType: ErrMissingFile, ErrNoCookie, ErrHeaderTooLong. Yet more utilize errors.New(“constant message”), but don’t save off a single value to compare against (i.e., they do errors.New(“constant message”) for each instance of the error).
This would be more compelling if the author gave any indication they had ever heard of sum types, or mentioned a language (such as Rust or Haskell) which uses them for error values.
I have a higher standard for elegance.
As a plus, it also works on generic integer types. /troll ;)
My beef with Go’s error handling is that it’s too simple, and not consistent. For one, many places in the standard library make it impossible to distinguish between the types of errors that occur.
Take for instance, the errors returned by the http library. More often than not the only way to distinguish what happened (and handle it differently) is to look at the string representation of the error, and they are almost never consistent!
Examples:
badStringError)Some of these errors are saved off via errors.New() so you can actually compare a known error against them, or exist as a
ProtocolErrorType:ErrMissingFile,ErrNoCookie,ErrHeaderTooLong. Yet more utilize errors.New(“constant message”), but don’t save off a single value to compare against (i.e., they do errors.New(“constant message”) for each instance of the error).This is simply maddening to me!
This would be more compelling if the author gave any indication they had ever heard of sum types, or mentioned a language (such as Rust or Haskell) which uses them for error values.
I’d love to have an article flag that says “incorrect”.