+
Skip to content

aleics/result

Repository files navigation

result

This library offers and experiments with a variant of the standard Result type for safer error handling, where the failure is strongly typed. Thus, it's easily understood by the compiler, which exception can be expected out of a given operation.

Inspired by the strongly typed Result from the Rust programming language 🦀.

import me.aleics.result.Result

fun div(x: Double, y: Double): Result<Double, MathException> {
    ...
}

fun main() {
    val result = div(2.0, 3.0)

    when (result) {
        is Result.Success -> println("Division result is ${result.value}")
        is Result.Failure -> throw result.exception // I can't handle `MathException`, I give up
    }
}

Then, Result can be returned and be handled properly, without any unexpected exceptions being thrown. If a given failure shouldn't be handled, we can always throw such exception as a last resort.

Result can be chained together by using a handful of operators, which allow to handle successes and failures properly. It is also extremely helpful for libraries, which shouldn't have the responsibility to throw an exception, and therefore crashing the program that they are running in.

object Token
object Expression
object Execution

sealed class InterpreterException : Exception() {
    class TokenizationException : InterpreterException()
    class ParsingException: InterpreterException()
    class ExecutionException : InterpreterException()
}

class Interpreter {
    fun run(input: String): Result<Execution, InterpreterException> =
        tokenize(input)
            .flatMap { parse(it) }
            .flatMap { execute(it) }

    private fun execute(expression: Expression): Result<Execution, InterpreterException> { ... }

    private fun parse(tokens: List<Token>): Result<Expression, InterpreterException> { ... }

    private fun tokenize(input: String): Result<List<Token>, InterpreterException> { ... }
}

fun main() {
    val input = "2 + 3"

    val interpreter = Interpreter()

    interpreter.run(input)
        .onSuccess { "Result: $it" }
        .onFailure { exception -> "Error while running interpreter: ${exception.message}"  } // InterpreterException
}

The Kotlin Team is well aware of this better structure for the Result type, and we might see it once inline sealed classes are supported.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载