Maybe Another Way of Error Handling ...
Last update: December 7, 2024 pm
Errors!
Throw exceptions!
That seems simple, but is it? Let’s define a simple function with some boundary conditions. For example, division is undefined if the denominator is 0.
1 |
|
What’s wrong with this function?
At the very first line,
we defined safeDiv
as a mapping take takes two double
and returns a double
.
But when the function throw a runtime error,
does it return a double
?
Then, out function header is lying to us!
As a careful programmer, we always want out function to be honest. In a program, the type of a function should indicate what the function does.
Maybe it Returns a …
Let’s stay on the example of safeDiv
.
Since the denominator cannot be 0
if we get a 0 for the denominator but cannot throw an exception,
what should we do?
In this case, the return value cannot be a double
neither.
Actually, we say the safe division maybe returns a double, or nothing.
- if the denominator is 0,
safeDiv
returns Nothing, - otherwise, it returns just the division.
That is,
1 |
|
it returns
1 |
|
which is exactly what the type signature tells us!
This idea words on more generic function too. For example, when we want the head of an empty list, there would be an error
1 |
|
We can define a safeHead
function to solve this problem,
1 |
|
our we can just use the Prelude head
1 |
|
this will give us
1 |
|
Composition with Error
Function composition is the highest call in functional programming. For example, if we want to convert a division result to string
1 |
|
The type signature of show
is
1 |
|
and if we compose it with show
with our safeDiv
1 |
|
we will need another parser to extract the division result.
In a simple way,
we may define a safeShow
to solve this problem.
1 |
|
1 |
|
But our safeShow
only handles the Maybe Double
type.
We cannot compose it with other type functions,
which contradicts the idea of function reusability.
Ideally, we want to keep show
‘s generic type in our safeShow
,
while extracting the result easily and quickly.
To solve these two problems, we may define safeShow
as
- if
safeShow
receives nothing, it returns nothing - otherwise it returns just the
show
of the value
We introduce the >>=
bind operator.
Let’s see how it works.
First, we can define the safeShow
as we want:
it takes any showable type and the return type maybe is string.
1 |
|
Then we can try in ghci
1 |
|
>>=
is the composition operator of functions that return a Maybe type!
What’s its type in this case?
1 |
|
This function takes two inputs
Maybe a
as the output of our othersafe*
functions;- a function that map
a
toMaybe b
type.
The actual type of >>=
is
1 |
|
You may wonder what is Monad m
, and as mentioned before in type signature of show
, Show a
.We said Show a
means “showable” type.In fact, the keywords Monad
and Show
are type class.Visit blog post “Types! What are They?”.
We said >>=
is a composition operator,but why it does not take two functions?If you are interested in that,visit blog post “Object Oriented Mathematics !?”.
For more information,visit A Fistful of Monads.
All blog follow CC BY-SA 4.0 licenses, please cite the creator when reprinting.