如何对 Set[ValidatedNel[String, Double]] 求和?
How to sum a Set[ValidatedNel[String, Double]]?
我有这个:
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))
}
我无法创建经过验证的 NelNumeric...
首先:在这种情况下使用集合感觉有点奇怪(对于 Validated[..., Double]
值的集合)。您关心 Set
语义的哪一部分?无序性?唯一性?
通常,总结具有 Monoid
实例的元素的最直接方法是对具有 Foldable
实例的事物使用 combineAll
方法——例如 List
(但不是 Set
)。
import cats.data.{ Validated, ValidatedNel }
import cats.instances.double._, cats.instances.list._
import cats.syntax.foldable._
// or just import cats.implicits._
val val1: ValidatedNel[String, Double] = Validated.valid(1.0)
val val2: ValidatedNel[String, Double] = Validated.valid(2.0)
val bad1: ValidatedNel[String, Double] = Validated.invalidNel("foo")
val bad2: ValidatedNel[String, Double] = Validated.invalidNel("bar")
val values = Set(val1, val2)
val withSomeBadOnes = Set(val1, bad1, val2, bad2)
然后:
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))
我猜你说的 "If some elements in the values are then I would like to have matching strings" 就是这个意思?
您也可以使用 SortedSet
,因为 Cats 为 SortedSet
提供了一个 Foldable
实例,但它并不方便:
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))
您还可以使用标准 fold
和 |+|
运算符来表示幺半群:
scala> values.fold(Validated.valid(0.0))(_ |+| _)
res4: cats.data.ValidatedNel[String,Double] = Valid(3.0)
总而言之:您不能直接在 Set
上调用 combineAll
,因为 Cats 没有为 Set
提供 Foldable
。我建议在任何情况下仔细重新考虑您对 Set
的使用,但如果您决定坚持使用它,您有几个选择:像我一样转换为 List
或 SortedSet
以上,在 Set
上使用标准的 fold
,或者最终编写您自己的 Foldable[Set]
或使用来自 alleycats 的
我有这个:
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))
}
我无法创建经过验证的 NelNumeric...
首先:在这种情况下使用集合感觉有点奇怪(对于 Validated[..., Double]
值的集合)。您关心 Set
语义的哪一部分?无序性?唯一性?
通常,总结具有 Monoid
实例的元素的最直接方法是对具有 Foldable
实例的事物使用 combineAll
方法——例如 List
(但不是 Set
)。
import cats.data.{ Validated, ValidatedNel }
import cats.instances.double._, cats.instances.list._
import cats.syntax.foldable._
// or just import cats.implicits._
val val1: ValidatedNel[String, Double] = Validated.valid(1.0)
val val2: ValidatedNel[String, Double] = Validated.valid(2.0)
val bad1: ValidatedNel[String, Double] = Validated.invalidNel("foo")
val bad2: ValidatedNel[String, Double] = Validated.invalidNel("bar")
val values = Set(val1, val2)
val withSomeBadOnes = Set(val1, bad1, val2, bad2)
然后:
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))
我猜你说的 "If some elements in the values are then I would like to have matching strings" 就是这个意思?
您也可以使用 SortedSet
,因为 Cats 为 SortedSet
提供了一个 Foldable
实例,但它并不方便:
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))
您还可以使用标准 fold
和 |+|
运算符来表示幺半群:
scala> values.fold(Validated.valid(0.0))(_ |+| _)
res4: cats.data.ValidatedNel[String,Double] = Valid(3.0)
总而言之:您不能直接在 Set
上调用 combineAll
,因为 Cats 没有为 Set
提供 Foldable
。我建议在任何情况下仔细重新考虑您对 Set
的使用,但如果您决定坚持使用它,您有几个选择:像我一样转换为 List
或 SortedSet
以上,在 Set
上使用标准的 fold
,或者最终编写您自己的 Foldable[Set]
或使用来自 alleycats 的