Объединение нескольких экземпляров `Try` разных типов результатов в качестве аппликативов - PullRequest
0 голосов
/ 13 ноября 2018

Существует ли API для объединения Try экземпляров в Vavr, который аналогичен тому, как работает аппликативный оператор Scalaz |@|?

В частности, если у меня более двух Try экземпляров, дляНапример, Try<X>, Try<Y> и Try<Z>, я хотел бы объединить эти экземпляры аппликативным способом, используя функцию с тремя аргументами.

Я ищу сигнатуру функции, которая похожа на:

static <X, Y, Z, R> Try<R> combine(Try<X> x, Try<Y> y, Try<Z> z, Function3<X,Y,Z,R> func

1 Ответ

0 голосов
/ 15 ноября 2018

Насколько я понимаю, он не поддерживает это использование напрямую. Однако вы можете добиться этого с помощью flatMap:

static <X, Y, Z, R> Try<R> combine(Try<X> tx, Try<Y> ty, Try<Z> tz, Function3<X,Y,Z,R> func) {
    return tx.flatMap(x -> ty.flatMap(y -> tz.map(z -> func.apply(x, y, z))));
}

Если каждое значение Try содержит один и тот же тип, вы можете использовать операцию sequence:

public static void main(String[] args) {
    List<Try<String>> lt = List.of(Try.success("A"), Try.success("B"), Try.success("C"));
    Try<List<String>> tl = sequence(lt);
    System.out.println(tl);
}

static <T> Try<List<T>> sequence(List<Try<T>> lt) {
    return lt.foldRight(
        Try.success(List.empty()),
        (tt, tl) -> tt.flatMap(t -> tl.flatMap(l -> Try.success(l.prepend(t))))
    );
}

Если вы сравните типы ввода и вывода, вы увидите, что это по существу меняет положение контейнеров Try и List. Это довольно идиоматично для монад, хотя обычно вы реализуете его с помощью аппликативных операций с картами вместо flatMap.

В качестве альтернативы используйте Validation , который предназначен для использования в аппликативном стиле (через Validation.combine).

...