Распаковать значение из Either ‹L, R› vavr

Фон

У меня есть небольшая функция, которая может возвращать Either<String, Float>. В случае успеха он возвращает число с плавающей запятой, в противном случае - строку с ошибкой.

Моя цель - выполнить ряд операций в конвейере и достичь программирования, ориентированного на железную дорогу, с помощью Either.

Код

import java.util.function.Function;
import io.vavr.control.Either;

@Test
public void run(){

    Function<Float, Either<String, Float>> either_double = num -> {
        if(num == 4.0f)
            Either.left("I don't like this number");
        return Either.right(num * 2);
    };

    Function<Float, Float> incr = x -> x + 1.0f;

    Float actual = 
       Either.right(2f)
        .map(incr)
        .map(either_double)
        .get();

    Float expected = 6.0f;

    assertEquals(expected, actual);
}

Этот код выполняет ряд простых операций. Сначала я создаю одно из правых значений со значением 2, затем увеличиваю его и заканчиваю его удвоением. Результат этих операций - 6.

Проблема

Результат математических операций - 6.0f, но это не то, что я получаю. Вместо этого я получаю Right(6.0f).

Это проблема, которая препятствует компиляции кода. У меня есть значение в коробке внутри монады Either, но после проверки их API для Either Я не нашел способа распаковать его и получить значение как есть.

Я думал об использовании getOrElseGet, но даже этот метод возвращает Right.

Вопрос

Как мне получить доступ к реальным значениям, хранящимся в монаде Either?


person Flame_Phoenix    schedule 11.01.2019    source источник


Ответы (1)


Используйте flatMap(either_double) вместо map(either_double).

person talex    schedule 11.01.2019
comment
Я все еще получаю сообщение об ошибке: метод flatmap (Function ‹Float, Either‹ String, Float ››) не определен для типа Either ‹Object, Float› - person Flame_Phoenix; 11.01.2019
comment
Укажите явный тип для Either.right(2f) (Either.<String, Float>right(2f)) - person talex; 11.01.2019
comment
Приводит к еще одной ошибке: метод flatmap (Function ‹Float, Either‹ String, Float ››) не определен для типа Either ‹String, Float›. Мне не хватает какой-то операции по соединению карты и плоской карты? - person Flame_Phoenix; 11.01.2019
comment
M - заглавная буква flatMap - person talex; 11.01.2019
comment
Ах, официально я идиот. Хорошо проверено! Не могли бы вы добавить к своему ответу явный тип? Я все равно собираюсь принять это, но это будут будущие читатели. - person Flame_Phoenix; 11.01.2019
comment
Если он наконец компилируется, вы можете попытаться удалить явный тип из right, теперь он сможет правильно его угадать. - person talex; 11.01.2019