使用序列是否是为元数大于 1 的函数提供单子参数的正确方法?
Is using sequence the right approach to give monadic arguments to a function of arity greater than 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 个参数,只有当所有参数都是 right 参数时,我才想给它们。也就是说,sequence
将应用每个 monadic 值,因此我将它们作为单个 right 包含原始 fun1
、fun2
、fun3
return 个值。
这是推荐的方法吗?
不,我不会将 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)
。当 fun4
returns 一个 Either 时需要 unnest
,这可能不是必需的。
查看以下代码片段:
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 个参数,只有当所有参数都是 right 参数时,我才想给它们。也就是说,sequence
将应用每个 monadic 值,因此我将它们作为单个 right 包含原始 fun1
、fun2
、fun3
return 个值。
这是推荐的方法吗?
不,我不会将 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)
。当 fun4
returns 一个 Either 时需要 unnest
,这可能不是必需的。