Skip to content

Instantly share code, notes, and snippets.

@dam5s

dam5s/Result.kt

Last active Jun 4, 2020
Embed
What would you like to do?
Railway oriented programming in Kotlin - This is code accompanying my blog post https://medium.com/@its_damo/error-handling-in-kotlin-a07c2ee0e06f
sealed class Result<A, E> {
fun <B> map(mapping: (A) -> B): Result<B, E> =
when (this) {
is Success -> Success(mapping(value))
is Failure -> Failure(reason)
}
fun <B> bind(mapping: (A) -> Result<B, E>): Result<B, E> =
when (this) {
is Success -> mapping(value)
is Failure -> Failure(reason)
}
fun <F> mapFailure(mapping: (E) -> F): Result<A, F> =
when (this) {
is Success -> Success(value)
is Failure -> Failure(mapping(reason))
}
fun bindFailure(mapping: (E) -> Result<A, E>): Result<A, E> =
when (this) {
is Success -> Success(value)
is Failure -> mapping(reason)
}
fun orElse(other: A): A =
when (this) {
is Success -> value
is Failure -> other
}
fun orElse(function: (E) -> A): A =
when (this) {
is Success -> value
is Failure -> function(reason)
}
fun orNull(): A? =
when (this) {
is Success -> value
is Failure -> null
}
}
data class Success<A, E>(val value: A) : Result<A, E>()
data class Failure<A, E>(val reason: E) : Result<A, E>()
@kashzonal

This comment has been minimized.

Copy link

@kashzonal kashzonal commented Feb 21, 2020

Nice blog post. I think it could be improved by doing this:

sealed class Result<out T, out Error>
data class Success<T>(val value: T): Result<T, Nothing>()
data class Failure<Error>(val error: Error): Result<Nothing, Error>()

fun <T> Result<T, *>.orElse(other: T) = if (this is Success) value else other
fun <C,T> Result<T, *>.map(f: (T) -> C) = if (this is Success) Success(f(value)) else this
fun <C,T> Result<T, *>.flatMap(f: (T) -> Result<C, *>) = if (this is Success) f(value) else this
fun <E,C> Result<*, E>.mapFailure(f: (E) -> C) = if (this is Failure) Failure(f(error)) else this

fun <T,E> Result<T,E>.orElse(f: (E) -> T) = when (this) {
    is Success -> value
    is Failure -> f(error)
}
@dam5s

This comment has been minimized.

Copy link
Owner Author

@dam5s dam5s commented Feb 24, 2020

Updated with more readable version.

@aleksandar78

This comment has been minimized.

Copy link

@aleksandar78 aleksandar78 commented Mar 17, 2020

Very nice code example. I'm using Kotlin for the server-side project and I'm of the idea that Exception is fine for "exceptional" error propagation but in 99% of cases it becomes control flow, and that's not good.
Railway error handling is a very nice pattern and I'll take this code sample as a prototype for our internal lib.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.