Scala 如何对集合[ValidatedNel[String,Double]]求和?

Scala 如何对集合[ValidatedNel[String,Double]]求和?,scala,functional-programming,scala-cats,Scala,Functional Programming,Scala Cats,我有这个: Set[ValidatedNel[String, Double]] 我想将其中的双倍相加得到: ValidatedNel[String, Double] 如果值中的某些元素是匹配的,那么我希望有匹配的字符串 我玩Set.sum和Numeric都没用 以下是我想要达到的目标的测试: test("Summing ValidatedNel works") { val val1: ValidatedNel[String, Double] = Valid(1.0) v

我有这个:

Set[ValidatedNel[String, Double]] 
我想将其中的双倍相加得到:

ValidatedNel[String, Double]
如果值中的某些元素是匹配的,那么我希望有匹配的字符串

我玩Set.sum和Numeric都没用

以下是我想要达到的目标的测试:

  test("Summing ValidatedNel works") {
    val val1: ValidatedNel[String, Double] = Valid(1.0)
    val val2: ValidatedNel[String, Double] = Valid(2.0)
    val values: Set[ValidatedNel[String, Double]] = Set(val1, val2)

    val validatedNelNumeric: Numeric[ValidatedNel[String, Double]] = ???
    val sum = values.sum(validatedNelNumeric)

    assert(sum == Valid(3.0))
  }

我无法创建validatedNelNumeric…

首先:在这种情况下使用集合感觉有点奇怪(对于
Validated[…,Double]
值的集合)。您关心
集合
语义的哪一部分?混乱?独特性

一般来说,总结具有
幺半群
实例的元素最直接的方法是使用
combineAll
方法处理具有
可折叠
实例的对象,例如
列表
(而不是
集合

然后:

scala> values.toList.combineAll
res0: cats.data.ValidatedNel[String,Double] = Valid(3.0)

scala> withSomeBadOnes.toList.combineAll
res1: cats.data.ValidatedNel[String,Double] = Invalid(NonEmptyList(foo, bar))
我猜这就是你所说的“如果值中的某些元素是匹配的,那么我希望有匹配的字符串”的意思吧

您也可以使用
SortedSet
,因为CAT为
SortedSet
提供了一个
可折叠的
实例,但它并不方便:

scala> import cats.implicits._
import cats.implicits._

scala> import scala.collection.immutable.SortedSet
import scala.collection.immutable.SortedSet

scala> (SortedSet.empty[ValidatedNel[String, Double]] ++ values).combineAll
res2: cats.data.ValidatedNel[String,Double] = Valid(3.0)

scala> (SortedSet.empty[ValidatedNel[String, Double]] ++ withSomeBadOnes).combineAll
res3: cats.data.ValidatedNel[String,Double] = Invalid(NonEmptyList(bar, foo))
您还可以对幺半群使用标准的
折叠
|+|
操作符:

scala> values.fold(Validated.valid(0.0))(_ |+| _)
res4: cats.data.ValidatedNel[String,Double] = Valid(3.0)

总而言之:你不能直接在你的
集合上调用
combineAll
,因为猫没有为
集合提供可折叠的
。我建议您在任何情况下都要仔细重新考虑使用
集合
,但如果您决定坚持使用它,您有几个选择:像上面一样转换到
列表
分类集
,在
集合
上使用标准的
折叠
,或者最后编写您自己的
折叠[集合]
或使用alleycats中的一个。

如何求和
集合(val1,val2,无效(List(“a”,“b”).toNel,无效(List(“c”,“d”).toNel))
?如果没有集合,而是有一个列表,则可以执行
val sum:ValidatedNel[String,Double]=值。combineAll
。您需要导入
cats.instances.list.\u
cats.syntax.foldable.\u
。“如果且仅当,如果组中至少有一名患者,你想以一名患者结束。”@LuisMiguelMejíaSuárez是的,我没有最小化导入。我以后会这样做。我可以使用一个列表,所以一切都很好,它可以工作:)但是最后我想添加一些接近案例类MontantEnEur(montant:Double)的内容,如何让
combineAll
对用户定义的类型工作?我是猫的新手,抱歉:$忘记我之前的评论,我发现它:`implicit val montantEnEurAdditionMonoid:monotteneur]=new Monoid[MontantEnEur]{def empty:MontantEnEur=MontantEnEur(0.0)def combine(x:MontantEnEur,y:MontantEnEur):MontantEnEur=MontantEnEur(x.montant+y.montant)}“再次非常感谢:)旁注:我不会在评论中写空行,对不起:$
scala> values.fold(Validated.valid(0.0))(_ |+| _)
res4: cats.data.ValidatedNel[String,Double] = Valid(3.0)