Объединение функций, возвращающих Vavr Either - PullRequest
1 голос
/ 07 мая 2020

У меня есть ряд функций, которые принимают объект Request и возвращают Vavr Either.

Either будет содержать объект Result, если задача завершена, или измененный объект Request, если задача должна быть завершается другой функцией.

Мысль заключалась в том, что я мог бы связать их вместе, сделав что-то вроде этого:

// Note: The Request object parameter is modified by the function 
// before being returned in the Either.
Function<Request, Either<Request,Result>> function1;
Function<Request, Either<Request,Result>> function2;
Function<Request, Either<Request,Result>> function3;
Function<Request, Result> terminalFunction;

Result result = function1.apply(request)
            .flatMapLeft(function2)
            .flatMapLeft(function3)
            .fold(terminalFunction, r->r);

Но, видимо, flatMapLeft - это не вещь, поэтому я просто получаю вложенный Eithers на левая сторона. Любые идеи о том, как я могу достичь этой функции? Я открыт для альтернативных библиотек.

Изменить:

Result result = function1.apply(request)
            .fold(function2, Either::right)
            .fold(function3, Either::right)
            .fold(terminalFunction, r->r);

Похоже, это должно работать, но Intellij выдает эту ошибку во второй строке сгиба:

no instance(s) of type variable(s) exist so that capture of ? extends Object conforms to Request

Ответы [ 2 ]

2 голосов
/ 08 мая 2020

Вам нужна композиция monadi c на вашей Request стороне, которая находится слева в ваших сигнатурах типа, но у вас есть композиция monadi c для Either с правой стороны. Таким образом, вам нужно поменять местами оба в своих определениях функций или вы должны передать их через Either.swap() на

Function1.of(SomeType::function1).andThen(Either::swap)

По сути, каждый из ваших function[1-3] будет иметь тип:

Function<Request, Either<Result, Request>>

Тогда ваша цепочка вызовов станет:

Result result = function1.apply(request)
        .flatMap(function2)
        .flatMap(function3)
        .swap()
        .getOrElseGet(terminalFunction);
0 голосов
/ 07 мая 2020
Result result = function1.apply(request)
            .fold(function2, Either::<Request, Result>right)
            .fold(function3, Either::<Request, Result>right)
            .fold(terminalFunction, r->r);

Кажется, это работает, хотя немного неуклюже. Это злоупотребление библиотекой? Было бы интересно услышать некоторые альтернативные подходы.

...