缩小/折叠在monoid列表上,但是reducer返回

时间:2019-06-04 22:11:38

标签: scala functional-programming scala-cats

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

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

它是一个虚拟实现,但fn可能失败,因此它返回一个。然后,我有了一个要通过reduce / fold传递的值的列表。我能想到的最好的方法(假设List的类型是一个monoid)是

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

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

它有点笨拙,并且作为一种相当通用的模式,我怀疑有更好的方法来使用猫。

1 个答案:

答案 0 :(得分:7)

您可能想看看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]

因此,在您的情况下,type(-constructor)参数将统一如下:

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

以使f: (A, B) => G[B]成为f: (String, String) => Either[String, String],这恰好是combiner转换为函数时的类型。