减少/折叠幺半群列表但减少 returns 要么

Reduce / fold over list of monoid but reducer returns Either

我发现自己遇到过几次这样的情况,我有一个减速器/组合 fn,就像这样:

  def combiner(a: String, b: String): Either[String, String] = {
    (a + b).asRight[String]
  }

它是一个虚拟实现,但 fn 可能会失败,所以它 returns 要么。然后我有一个值列表,我想通过 reduce / fold 传递它。我能想到的最好的(假设列表的类型是幺半群)是这样的:

  def combine(items: Vector[String]) = {

    items.foldLeft(Monoid[String].empty.asRight[String]) { case (acc, value) =>
      acc.flatMap( accStr => combiner(accStr, value))
    }
  }

它有点笨拙,而且由于它是一个相当通用的模式,我怀疑有更好的方法使用猫来完成它。

您可能想看看 foldM。您的代码将大致如下所示:

Foldable[Vector].foldM(items, "")(combiner)

foldM 方法具有签名

def foldM[G[_], A, B](fa: F[A], z: B)(f: (B, A) ⇒ G[B])(implicit G: Monad[G]): G[B]

因此在您的情况下,类型(-构造函数)参数将统一如下:

  • G[X] = Either[String, ?]
  • A = String
  • B = String
  • F[X] = Vector[X]

这样 f: (A, B) => G[B] 就变成了 f: (String, String) => Either[String, String],这正是 combiner 转换为函数时的类型。