It really depends on what you call errors (and exceptions)
Exceptions normally refers to problem which happen exceptionnaly (i.e pretty much never), for example disk full, network error etc …
They are normally not part of the normal workflow and most of the times you can’t do anything about it, apart from catching it at the top level and display and exit gracefully.
In that case it’s not really different from not doing anything.
Then there are errors. What do you call an error ?
If you try to lookup a value in a list (or map) and you don’t find it : is it an error (because you know it should be there), or just something which can happen.
The first case might happen because you are looking for the value flag in a list of options and you know that it should be there.
In that case, you probably should change your data structure to something which enforce the presence of this value.
The other case, for example you have a list (or a map) of pair name and their plural form. You are only expecting the irregular plurals to be part of the list so returning Maybe
is fine.
Not finding it is not an error and you don’t need to know where it fails because it hasn’t fail.
For example to get the plural of a word you’ll have
plural :: Map String String -> String -> String
plural irregularMap name = fromMaybe (name ++ "s") (lookup name irregularMap)
I use fromMaybe
to deal with “error” nothing in irregularMap
. There is no error to propagate.
Using either is usually needed when you need to report an error to the user which gave you an invalid input.
This is unavoidable if the input is a for example a text file which needs to be parsed but can be avoid most of the time by a better UI.
If you are not doing user facing application, but for example a script to draw a chart from data in a database you shouldn’t need to know “where it failed”, because nothing should fail (option 1 & 3).