Post 9 – Maybe & Result

Tram Ho

One of the guarantees when we write programs in static-typing environments is that we will be able to avoid seeing the program run into errors. In addition to the static type reason, another part is because we are allowed to define program exceptions just like any other meaningful data type. And from there, we can create logic to give the necessary responses to exceptions that arise during operation.

Suppose when interacting with user input and collecting age information, we will be able to define the data type like this:

And in all cases, the input from the user can be passed to a valid toAge program. Appropriate input values ​​will result in Age 21 or Age 1001 , while values ​​that do not match will result in InvalidInput . We can then use Pattern Matching to ensure that both Age Int and Invalid Input cases are met properly and so the program won’t stop unexpectedly.

This type of processing will appear frequently. For example, when writing a single-page SPA application to interface a blog site and encapsulate the Post article content entered by the user to send to the server ; Obviously, we don’t want the data cases like the user forgetting to enter the Title or sending the draft without entering the Content content to wait for sending/receiving from the server . To recognize and provide immediate response logic to the user in these cases, we can define a MaybePost type similar to MaybeAge in the above example.

With a viewPreview to preview the contents of valid Post , we will now be able to display case-specific error messages and prompt the user.

Exception handling like this is extremely common, and performance is best when you fully define the exact exception types with the context to be handled. However, in many cases of simple exception handling, you can use Elm ‘s built-in exception descriptors. So now we will learn about Maybe and Result .

Maybe

Module: elm/core/Maybe

We’ve met Maybe in previous posts. and as we become familiar with Elm , we will see Maybe again very often.

This is a Union type union that has two variants, Just and Nothing . Where Just is a simple wrapper type that can hold a value of any data type including primitive and structured. Nothing is a special value that represents the case of meaningless data.

Two basic exception handling cases with Maybe are programs with partial logic for handling Partial Function and when you want to describe data record structures with optional Optional Field .

A Partial Function is when we write a sub-program that only wants to give results for certain data cases and say Nothing for other cases. Take for example Elm ‘s built-in String.toFloat converter.

And Optional Field are optional fields when we create data structures that describe records like this for example.

The point worth mentioning is that Elm ‘s compiler and language design creates the constraint that: If we write a sub-program that processes the data of these records, Maybe will inevitably cause us to have Pattern Matching . but can’t ignore possible user input cases.

Result

Module: elm/core/Result

The Maybe type can help us create the constraint that we need to write code to handle the situation for Exception . But it can’t help us to describe the cause when an exception occurs. For example, when we try to compile the code and the compiler simply displays a Nothing result, we will have a lot of trouble figuring out where and why this result is generated in the code.

This is what makes the Result type appear and be useful. We can use Result to type-hint for potentially unsuccessful operations.

If the processing logic succeeds, the result will be a value wrapped in Ok , and if the processing logic fails, the return result will be an Err value.

Now we can not only check the validity of age , but also give specific error message depending on different input cases by user. This type of response is clearly better than Nothing .

The Result type can also help us recover the program’s processing logic for retry at a later time. A good example is when we send an HTTP request to query data from a certain source. Query results may not be available in a variety of ways.

We should certainly be able to display the appropriate error messages as seen in the previous example. But we can also recover the processing logic to try sending the data query request again if we see the Timeout because most likely the error generated is just random and temporary. If it’s BadStatus 404 then obviously we don’t need to bother trying to send the request again.

Maybe & Result in JS

Because of JavaScript ‘s language design and operating environment, we won’t get the binding mechanism that requires exception handling logic like Maybe . Instead, we’ll need to get in the habit of writing configurations first to enumerate possible data cases and then design Error types to describe in detail when null results are received.

The only caveat about writing exception handling code is that we should focus on the top layer, closest to the code that responds to the request, in any route handling. Suppose we have a sub-program that is called first and then that sub-program will again delegate some of the work to another sub-program and so on until the n sub-program . As such, we should only try to write try..catch once in the first sub-program and create handling logic for the defined Error types.

Ah.. that is scattered for the case of complex processing logic and really necessary. As for the inputAge example above, the most important thing is that we need to carefully read the configuration of the supporting sub-program that JS provides to be able to predict the input results and change the data type.

(unpublished) [Declarative Programming + Elm] Lesson 10 – Elm Architecture

Share the news now

Source : Viblo