kotlinarrows

Kotlin Arrow make piece of code functional


I am having trouble refactoring this function here. How can I make it functional, in a way that instead of nested when-is you have sequential mappings/aggregations of LEFT=ErrorCodes? And if I wanted to add a try-catch-block to it, how would I make that functional? I am using 1.2.0-RC but have no objections downgrading it.

when(val maybeValid = ValidInput.create(uncheckedInput)) {
    is Either.Right -> {
        val validInput = maybeValid.value
        when(val maybeResult = Result.create(validInput)) {
            is Either.Right -> {
                TRY/CATCH, RETURN LEFT ON CATCH, RESULT ON RIGHT
            }
            is Either.Left -> { RETURN LEFT })) }
        }
    }
    is Either.Left -> maybeValid.leftOrNull()!!.map { RETURN LEFT }
}

I am just a bit overwhelmed of the toolset Arrow offers, originally I was just using Either as an advanced tuple, but I might as well aggregate the results in the way it is meant to be used.


Solution

  • You can refactor the nested when expressions to a more functional style by using map, flatMap, and fold. Additionally, you can use Try to handle exceptions in a functional manner. Here's a refactored version of your code that's more functional and includes a try-catch block using the Try class:

    fun processInput(uncheckedInput: String): Either<ErrorCodes, Result> {
    return ValidInput.create(uncheckedInput)
        .flatMap { validInput ->
            Result.create(validInput)
                .flatMap { result ->
                    Try {
                        // Perform the operation that might throw an exception
                        // Replace with your actual operation
                    }.fold(
                        { throwable -> ErrorCodes.ExceptionError(throwable).left() },
                        { result.right() }
                    )
                }
        }
    

    }

    Here's what the code does:

    This approach should give you a more functional and cleaner code structure, and you can easily add more steps to the process using flatMap if needed.