Является ли использование последовательности правильным подходом для предоставления монадических аргументов функции арности больше 1?

Смотрите следующий фрагмент кода:

const
  fun1 = () => Either.of(1),
  fun2 = () => Either.of(2),
  fun3 = () => Either.of(3),
  fun4 = curry((x, y, z) => Either.of(x + y + z)),
  fun5 = x => Either.of(x + 1),
  fun6 = () => pipeK(
    () => sequence(Either.of, [fun1(), fun2(), fun3()]),
    apply(fun4),
    fun5
  )(),

result = fun6() // returns 7

fun4 требует 3 аргументов, и я хотел бы дать их, только если все они являются правильными аргументами. То есть, sequence будет применять каждое монадическое значение, так что я получу их как одно право, связанное с необработанным fun1, fun2, fun3 возвращаемые значения

Это рекомендуемый подход?

Нажмите здесь, чтобы запустить весь фрагмент кода

1 ответ

Решение

Нет я бы не использовал sequence с массивом и apply, Я думаю, что более идиоматический подход заключается в использовании ap:

const fun6 = () => chain(fun5, unnest(ap(ap(ap(Either.of(fun4), fun1()), fun2()), fun3())));
// or
const fun6 = () => chain(fun5, unnest(ap(ap(map(fun4, fun1()), fun2()), fun3())));
// or
const fun6 = () => Either.of(fun4).ap(fun1()).ap(fun2()).ap(fun3()).chain(identity).chain(fun5);

Эквивалент в Haskell будет fun5 =<< join (fun4 <$> fun1 <*> fun2 <*> fun3), unnest необходимо, когда fun4 возвращает либо, что не может быть необходимым.

Другие вопросы по тегам