javafunctional-programmingvavr

Clean way to chain multiple Try results using Vavr


In my project I often have a pattern, where I chain multiple methods that may or may not succeed.
I struggle to find cleanest way to implement it using Vavr. Is there any other way to do it besides these two?
Optimally something that does not require me to create unnecessary lambdas where I don't even use the passed variable.

   // First way to do it: use flatMap to chain it
    public Try<String> mainMethod(String someParam) {
        return firstOperation()
                .flatMap(v -> secondOperation(someParam))
                .flatMap(v -> thirdOperation(someParam));
    }
   // Second way to do it: pattern matching
    public Try<String> otherMainMethod(String someParam) {
        Try<String> firstResult = firstOperation();
        return Match(firstResult)
                .of(
                        Case(
                                $Success($()),
                                () -> {
                                    Try<String> secondResult = secondOperation(someParam);
                                    return Match(secondResult)
                                            .of(
                                                    Case($Success($()), thirdOperation(someParam)),
                                                    Case($Failure($()), secondResult));
                                }),
                        Case($Failure($()), firstResult));
    }

    private Try<String> firstOperation() {
        return Try.of(
                () -> {
                    // do something
                });
    }

    private Try<String> secondOperation(String someParam) {
        return Try.of(
                () -> {
                    // Try something
                });
    }

    private Try<String> thirdOperation(String someParam) {
        return Try.of(
                () -> {
                    // Try something
                });
    }

Solution

  • An elegant solution is to use vavr's for comprehension:

    public Try<String> yetAnotherMainMethod(String someParam) {
       return API.For(firstOperation(), secondOperation(someParam), thirdOperation(someParam)).yield((s, s2, s3) -> s.concat(s2).concat(s3));
    }