Note: Kotlin has since added Result to its stdlib: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-result/index.html
A simple Result monad for Kotlin.
Extracted from kog.
repositories {
maven { url "https://jitpack.io" }
}
dependencies {
compile "com.danneu:kotlin-result:x.y.z"
// Or always get latest
compile "com.danneu:kotlin-result:master-SNAPSHOT"
}A Result represents an outcome of an operation that can succeed or fail.
Result.Okwraps the output value:result.valueResult.Errwraps the output error:result.error
The purpose of the abstraction is to provide a more functional
and composable way to handle errors than try/catch.
For an example, check out kittinunf/Result#why.
val okResult = Result.ok(42)
val errResult = Result.err("failure")Force-unwrap a result value.
Result.ok(42).getOrThrow() == 42
Result.err("failure").getOrThrow() // throws com.danneu.result.UnwrapExceptionUnwrap a result value with a fallback in case of error.
Result.ok(42).getOrElse(-1) == 42
Result.err("failure").getOrElse(-1) == -1Or pass in a function if you want to inspect or transform the error.
Result.err("failure").getOrElse { message ->
message + "-transformed"
} == "failure-transformed"Transform a result's value.
Result.ok(100).map { it + 1 } == Result.ok(101)
Result.err("failure").map { it + 1 } == Result.err("failure")Transform a result's error.
Result.ok(100).mapError { it + "-mapped" } == Result.ok(100)
Result.err("failure").mapError { it + "-mapped" } == Result.err("failure-mapped")Reduce both sides into a final value.
Result.ok(100).fold({ it + 1 }, { it + "-mapped" }) == 101
Result.err("failure").fold({ it + 1 }, { -1 }) == -1Transform result into a new result based on its value.
Like .map() except that the lambda returns a new result instead of a new value.
Result.ok(42).flatMap { Result.ok(100) } == Result.ok(100)
Result.err("failure").flatMap { Result.ok(100) } == Result.err("failure")Transform result into a new result based on its error.
Like .mapError() except that the lambda returns a new result instead of a new error.
Result.ok(42).flatMapError { Result.ok(100) } == Result.ok(42)
Result.err("failure").flatMapError { Result.ok(100) } == Result.ok(100)Combine a list of results into a single result.
Short-circuits on first error.
Result.all(ok(1), ok(2), ok(3)) == Result.ok([1, 2, 3])
Result.all(ok(1), err("failure"), ok(3)) == Result.err("failure")To represent a Result that can never fail, use Kotlin's Never:
fun add (a: Int, b: Int): Result<Int, Never> {
return Result.ok(a + b)
}Versus kittinunf/Result
kittinunf/Result is another Result monad library
implemented for Kotlin. However, it constrains
its Result value to non-null values and its error to instances
of Exception.
This library does not constrain either types. This means that it can model nullable result values and errors represented as any type, like a simple string error message or an integer error code.
For example, you can represent Result<User?, String> in this library
but not in kittinunf/Result.