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)