Gas Fire Pit

Monads are not Rocket Surgery— Part Two: Result

In Part One of this article, we learned about the Maybe monad. Maybe made it easier for us to safely handle null references in a functional pipeline. In Part Two, we will take a look at how the Result monad in KivaKit captures and handles failure information in a pipeline.

Result

The Result class subclasses Maybe and adds methods relevant to capturing failure messages. All the methods in Maybe work as expected, and treat a failure condition as if it was a null reference. This allows functional pipelines to ignore failures in the same way that Maybe allows them to ignore null values.

If we reduce Result to the key methods, we see:

class Result<Value> extends Maybe<Value>
{
static <T> Result<T> success(T value) {}
static <T> Result<T> failure(Throwable,
String message,
Object... arguments)
{}
static <T> Result<T> failure(String message,
Object... arguments)
{}
boolean succeeded() {}
boolean failed() {}

<Output, Mapper extends StringMapper<? extends Output>>
Maybe<Output> map(Class<Mapper> mapperType) {}
MessageList messages() { } static <T> Result<T> capture(Broadcaster value) {}
static <T> Result<T> run(Broadcaster, Code<T>) {}
}

Success and Failure

Result objects can be constructed to represent the success or failure of an operation. A successful result is created like this:

var result = Result.success(user);

If we call succeeded() on this result object, it will return true. We can retrieve the result value with result.get().

Failure Result objects can be constructed like this:

var result = Result.failure("Unable to launch rocket!");

If we call failed(), it will return true, and messages() will contain a Problem object with the message “Unable to launch rocket!”.

String Conversions

The kivakit-converters mini-framework provides a variety of StringConverters. All StringConverters are StringMappers, so they can be applied with the convert(StringMapper) method. For example, this code:

Result.success("5 minutes")
.convert(DurationConverter.class)
.get();

converts the string “5 minutes” to a Duration object.

The Result class creates a DurationConverter, passing this as the sole argument to its constructor. This connects the converter to Result, so it can capture any failure messages during the conversion. If the conversion fails, the result will be absent.

Capturing the Result of an Operation

Now for the interesting part. If we call Result.capture(Broadcaster) the Result object we get back will capture any failure messages that the given broadcaster transmits. For example:

class Operation extends BaseComponent implements Code<String>
{
String run() { }
}
var operation = new Operation();var result = Result.capture(operation);
operation.run();
return result;

If Operation.run() (which implements the Code interface) successfully returns a String, it will be captured in result, succeeded() will return true, and get() will return the value that was produce. If it fails by throwing an exception, or by broadcasting a Problem, the relevant failure message(s) will be contained in messages(), and failed() will return true.

We can do this all in one line as well:

return Result.run(operation, operation::run);

Conclusion

We learned in this article how to use the Result monad to represent a success or failure state. We can build function pipelines with Result that do not have to concern themselves with failures or null values. We can easily capture failures while executing code that can produce them.

Now we’re cooking with gas!

More about KivaKit

https://state-of-the-art.org/

https://www.kivakit.org/

--

--

--

TNAV, KivaKit, Apache Wicket, Lexakai, writer, doc filmmaker, peer-reviewed researcher, Meisner-trained actor, artist, designer, founder(3x), born skeptic

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Building a Custom Video Application — A million-dollar idea !!

Cara Install MongoDB pada Ubuntu 20.04 / Debian 11 / Linux Mint

Cara Install MongoDB pada Ubuntu 20.04 / Debian 11 / Linux Mint

Array Problems

Calling Cloud Composer to Cloud Functions and back again, securely

Create an Alias in Kubernetes for an External Web Service

Using Stripe with PHP

Bugfender 2.0 — Behind the Scenes

Make money with Crodo.io

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Jonathan Locke

Jonathan Locke

TNAV, KivaKit, Apache Wicket, Lexakai, writer, doc filmmaker, peer-reviewed researcher, Meisner-trained actor, artist, designer, founder(3x), born skeptic

More from Medium

What’s Different About Java 17 and Containers?

Monads are not Rocket Surgery— Part One: Maybe

Why we use Java at Jibit

An epic tale: comparing JDBC and R2DBC in a real-world scenario