条件函数的无点样式

pointfree style for a conditional function

我希望能得到一些帮助,以 pointfree 风格编写这篇文章。

对于上下文:该函数采用 Either 类型的数组和 returns 任务类型。任务类型被任何具有 left 集的 Either 类型拒绝。如果左侧集没有 Either 类型,则解决任务类型。以这种方式使用:

    Async.parallel(xs).             
        map(eachToEither).          
        chain(rejectAnyLefts).      
        fork(error, success)

在实践中我会添加另一个链(就在分叉之前)来执行持久化。但首先我要确保我的代码尽可能地简洁明了。手头的函数是 rejectAnyLefts,我想编写 pointfree,但有几件事让我陷入循环。

  1. the if
  2. the need for storing the leftObjs value to be used in the IF and potentially the return value
const rejectAnyLefts = function(eitherArray){
    const leftObjs = r.filter(r.propEq("isLeft", true), eitherArray)

    const isEmpty = r.propEq('length', 0)
    return (isEmpty(leftObjs)) ?
        Task.rejected(leftObjs) :
        Task.of(eitherArray)
}

如果您只对捕获第一个 Left 值感兴趣,那么这可以使用 R.sequence 定义,它将 [Either a b] 转换为 Either a [b]

R.pipe(R.sequence(Either.of), R.invoker(2, 'fold', Task.rejected, Task.of));

可以使用 Validation 类型而不是 Either,后者将合并所有 Failure 值,但是这需要 Failure 类型中的值实施 Semigroup 以允许它们合并。

要捕获并拒绝所有 Left 值,我们可以以无点形式对您现有的实施进行建模,例如:

R.pipe(R.partition(R.prop('isLeft')),
       R.ifElse(R.pipe(R.head, R.isEmpty),
                R.pipe(R.last, Task.of),
                R.pipe(R.head, Task.rejected)));

与您现有的实现相比,这是否变得更易读或更难读在很大程度上是主观的。