用Scalaz对OptionT[Future,BigDecimal]列表求和

用Scalaz对OptionT[Future,BigDecimal]列表求和,scala,sum,scalaz,Scala,Sum,Scalaz,我有一个类型为list[Result[BigDecimal]]的列表,我想求和 type Result[A]=OptionT[Future,A] 规则是,如果存在任何Future(None),那么我们将得到结果Future(None) 我有函数[]: 但是,我缺少Result[BigDecimal]的Monoid实例。如何使用Scalaz定义它 我不确定Scalaz为什么不提供这个实例,它确实提供了一个Monoid[Future[a]]其中a有一个Monoid实例,并且范围中有一个隐式执行上下文

我有一个类型为
list[Result[BigDecimal]]
的列表,我想求和

type Result[A]=OptionT[Future,A]

规则是,如果存在任何
Future(None)
,那么我们将得到结果
Future(None)

我有函数[]:

但是,我缺少
Result[BigDecimal]
Monoid
实例。如何使用Scalaz定义它


我不确定Scalaz为什么不提供这个实例,它确实提供了一个
Monoid[Future[a]]
其中
a
有一个Monoid实例,并且范围中有一个隐式执行上下文。不过,您可以通过定义
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
也可以):

不管它值多少钱,但是(像Scalaz中的
Future[Option[?]]
实例)它有
None
作为标识

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)(_ |+| _)
}
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)