在 Scalaz 中总结 OptionT[Future, BigDecimal] 列表
Summing a list of OptionT[Future, BigDecimal] in Scalaz
我有一个 List[Result[BigDecimal]]
类型的列表,我想对其求和。
type Result[A] = OptionT[Future, A]
规则是,如果有 Future(None)
,那么我们得到结果 Future(None)
。
我有函数[1]:
def sum[A: Monoid](as: List[A]): A = {
val M = implicitly[Monoid[A]]
as.foldLeft(M.zero)(M.append)
}
但是,我缺少 Result[BigDecimal]
的 Monoid
实例。如何使用 Scalaz 定义它?
我不确定为什么 Scalaz 不提供这个实例——它确实提供了一个 Monoid[Future[A]]
,其中 A
有一个幺半群实例,并且范围内有一个隐式执行上下文。不过,您可以通过在 Result
和 Future[Option[?]]
之间定义同构然后使用 IsomorphismMonoid
或 [这不会'通过直接定义一个实际上没有所需的语义]:
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scalaz._, Scalaz._
type Result[A] = OptionT[Future, A]
implicit def resultMonoid[A: Monoid]: Monoid[Result[A]] = new Monoid[Result[A]] {
def zero: Result[A] = Monoid[A].zero.point[Result]
def append(f1: Result[A], f2: => Result[A]): Result[A] = (f1 |@| f2)(_ |+| _)
}
然后(使用 Scalaz 自己的 suml
,但您的 sum
也可以):
scala> List(OptionT(Future(1.some)), OptionT(Future(2.some))).suml
res1: scalaz.OptionT[scala.concurrent.Future,Int] = OptionT(List())
scala> scala.concurrent.Await.result(res1.run, scala.concurrent.duration.Duration.Inf)
res2: Option[Int] = Some(3)
就其价值而言,Cats provides this instance,但是(就像 Scalaz 中的 Future[Option[?]]
实例一样)它具有 None
作为标识。
我有一个 List[Result[BigDecimal]]
类型的列表,我想对其求和。
type Result[A] = OptionT[Future, A]
规则是,如果有 Future(None)
,那么我们得到结果 Future(None)
。
我有函数[1]:
def sum[A: Monoid](as: List[A]): A = {
val M = implicitly[Monoid[A]]
as.foldLeft(M.zero)(M.append)
}
但是,我缺少 Result[BigDecimal]
的 Monoid
实例。如何使用 Scalaz 定义它?
我不确定为什么 Scalaz 不提供这个实例——它确实提供了一个 Monoid[Future[A]]
,其中 A
有一个幺半群实例,并且范围内有一个隐式执行上下文。不过,您可以通过在 Result
和 Future[Option[?]]
之间定义同构然后使用 IsomorphismMonoid
或 [这不会'通过直接定义一个实际上没有所需的语义]:
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scalaz._, Scalaz._
type Result[A] = OptionT[Future, A]
implicit def resultMonoid[A: Monoid]: Monoid[Result[A]] = new Monoid[Result[A]] {
def zero: Result[A] = Monoid[A].zero.point[Result]
def append(f1: Result[A], f2: => Result[A]): Result[A] = (f1 |@| f2)(_ |+| _)
}
然后(使用 Scalaz 自己的 suml
,但您的 sum
也可以):
scala> List(OptionT(Future(1.some)), OptionT(Future(2.some))).suml
res1: scalaz.OptionT[scala.concurrent.Future,Int] = OptionT(List())
scala> scala.concurrent.Await.result(res1.run, scala.concurrent.duration.Duration.Inf)
res2: Option[Int] = Some(3)
就其价值而言,Cats provides this instance,但是(就像 Scalaz 中的 Future[Option[?]]
实例一样)它具有 None
作为标识。