Deriving a Kotlin “Try” type

Functional programming languages like Scala often have a type called “Try” to hold the result of a computation if successful or to capture an exception on failure.

This is an incredibly useful type, allowing a caller to pointedly control how to handle an exceptional scenario. In this post I will try and create such a type from scratch.

As an example, I will be using the scenario from Daniel Westheide’s excellent introduction to the Try type in Scala

So my objective is to call a remote URL and return the content as a string. A few things can go wrong -

  • The url can be badly formed
  • The url may be wrong and may not have anything to retrieve content from

Let’s start with the first one, the URL being badly formed, an API call using the “Try” type would look something like this:

Here a URL is being parsed and the result is a valid url or an exception. So a Try type that can implement this much, would look something like this:

“Try” type has two sub types — A “Success” wrapping a successful result and a “Failure” capturing an exception from the call.

With the two subtypes in place, let’s extend the use of the Try type:

If I were to call using a badly formatted url like above with a wrong scheme “htt” instead of “http”, should result in a failure. So let’s implement the “isFailure” and “isSuccess” behavior:

That works nicely, so now that a url is available, hopefully valid, lets get some content from the URL:

which means that our “Try” type should have a “get()” method to retrieve the result if successful and can be implemented like this:

The Success path simply returns the result and the Failure path propagates the wrapped exception.

map Operation

Let’s take it a small step forward. Given a url say you want to return the host of the url:

While this works, the problem with the approach is that the “get()” call for an invalid url would result in an exception if the url is not valid to start with, so a better approach is to retrieve the host name only if the url is valid. Traditionally this is done using a “map” operator and an implementation looks like this:

and it behaves as expected.

flatMap Operation

Along the lines of “map” operation, now lets get back to the original scenario of validating the url and then attempting to get the content. Now the call to get content can also fail, so you would want that to be wrapped with a Try type also.

The two call needs to be chained together, and “map” operation may appear to be the right operator to use:

If you look at the response type now, it does not really line up, it is a “Try<Try<String>>” and not a “Try<String>”, this is exactly what a flatMap operation does. It takes a valid URL and returns just the inner wrapped result.

A test using it would look like this:

So how can “flatMap” be implemented, with a fairly simple code that looks like this:

One more small feature, given that Try type has two subtypes is to deconstruct the contents when required:

This assumes that the user knows the subtypes which may be an okay assumption to make for this type.

Conclusion

A type like “Try” is incredibly useful in capturing a result cleanly or with exception and provides a neat alternative to using a normal try..catch block. Here I showed a way to write such a type from scratch, however this may be an overkill, a better way to get such a type is to simply use an excellent library like vavr which has the Try type already built in. I feel it is instructive to create such a type from scratch though.

Here is the code in my github repository — https://github.com/bijukunjummen/fp-experiment-kotlin/blob/master/src/main/kotlin/sample/adt/Try.kt

Lead software Engineer with Nike

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