缩小/折叠在monoid列表上,但reducer返回
我发现自己有几次遇到减速器/像这样组合fn的情况:
Ive found myself in the situation a couple of times where i have a reducer / combine fn like so:
def combiner(a: String, b: String): Either[String, String] = {
(a + b).asRight[String]
}
它是一个虚拟实现,但fn可能失败,因此它返回一个.然后,我有了要通过reduce/fold传递的值的列表.我能想到的最好的方法(假设列表的类型是一个monoid)是:
Its a dummy implementation but the fn can fail so it returns an either. I then I have a list of values I want to pass through this with reduce / fold. The best I can come up with (assuming the List's type is a monoid) is this:
def combine(items: Vector[String]) = {
items.foldLeft(Monoid[String].empty.asRight[String]) { case (acc, value) =>
acc.flatMap( accStr => combiner(accStr, value))
}
}
它有点笨拙,并且作为一种相当通用的模式,我怀疑有更好的方法来使用猫.
Its a bit clumsy and as its a fairly generic pattern I suspect there's a better way to do it using cats.
You might want to take a look at foldM. Your code would then look approximately like this:
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)参数将统一如下:
so in your case, the type(-constructor) parameters would unify as follows:
-
G[X] = Either[String, ?]
-
A = String
-
B = String
-
F[X] = Vector[X]
G[X] = Either[String, ?]
A = String
B = String
F[X] = Vector[X]
,以使f: (A, B) => G[B]
变为f: (String, String) => Either[String, String]
,恰好是combiner
转换为函数时的类型.
so that f: (A, B) => G[B]
would become f: (String, String) => Either[String, String]
, which is exactly the type of combiner
when it's converted into a function.