marcoferrer
06/28/2017, 5:28 PMsealed class Result<T, E> {
abstract val value: T
abstract val error: E
abstract val isOk: Boolean
val isError:Boolean get() = isOk
@Suppress("UNCHECKED_CAST")
inline infix fun <U> map(f: (T) -> (U)): Result<U, E> = when (this) {
is Ok<T, E> -> Ok<U, E>(f(this.v))
is Error<T, E> -> this as Error<U, E>
}
@Suppress("UNCHECKED_CAST")
inline infix fun <U> mapErr(f: (E) -> (U)): Result<T, U> = when (this) {
is Ok<T, E> -> this as Ok<T, U>
is Error<T, E> -> Error<T, U>(f(this.e))
}
// MONAD
@Suppress("UNCHECKED_CAST")
inline infix fun <U> flatMap(f: (T) -> (Result<U, E>)): Result<U, E> = when (this) {
is Ok<T, E> -> f(this.v)
is Error<T, E> -> this as Error<U, E>
}
@Suppress("UNCHECKED_CAST")
inline infix fun <U> flatMapErr(f: (E) -> (Result<T, U>)): Result<T, U> = when (this) {
is Ok<T, E> -> this as Ok<T, U>
is Error<T, E> -> f(this.e)
}
}
data class Ok<T, E>(override val value: T) : Result<T, E>() {
override val error: E get() = throw RuntimeException("attempt to get error of ${this}")
override val isOk = true
}
data class Error<T, E>(override val error: E) : Result<T, E>() {
override val value: T get() = throw RuntimeException("attempt to get value of ${this}")
override val isOk = false
}