【问题标题】:Summing a list of OptionT[Future, BigDecimal] in Scalaz在 Scalaz 中汇总 OptionT[Future, BigDecimal] 列表
【发布时间】:2016-12-27 18:17:11
【问题描述】:

我有一个 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 定义它?

learning Scalaz - sum function

【问题讨论】:

    标签: scala sum scalaz


    【解决方案1】:

    我不确定为什么 Scalaz 不提供这个实例——它确实提供了一个 Monoid[Future[A]] ,其中 A 有一个 monoid 实例,并且在范围内有一个隐式执行上下文。不过,您可以轻松地创建自己的,方法是定义ResultFuture[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 作为标识。

    【讨论】:

      猜你喜欢
      • 2015-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多