我有一个方法:
def pollAll[T, O](orchestrators :Seq[O], poll :(O)=>Future[T])
(implicit reduce: (T, T) => T) :Future[T] =
(Future sequence orchestrators.map(poll(_))).map(res => res.reduce(reduce))
现在,让我们假设我有一个返回Future[Seq[A]]
的民意调查。是否可以为reduce
参数提供通用隐式值,该参数将任何两个序列与公共元素类型连接起来?像这样:
implicit def reduceSeq[T] = (s1 :Seq[T], s2 :Seq[T]) => s1 ++ s2
上述方法不起作用,因为隐式转换使用隐式方法,在查找隐式参数时不考虑它们的结果。
答案 0 :(得分:0)
我也没有发现您的解决方案有任何问题,但是scalaz定义了名为Semigroup
和Monoid
的类型,可以帮助您。它还包含许多常见类型的Semigroup
个定义,例如List和Int。 SemiGroup
定义了append操作。 Monoid
扩展Semigroup
,但另外提供zero
或初始值。如果orchestrators
可能为空,这将非常有用,在这种情况下,您可能需要foldLeft
而不是reduce
。
注意:我改变了您的类型参数
import scalaz._
import Scalaz._
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
def pollAll[O, T : Semigroup](orchestrators :Seq[O], poll :(O)=>Future[T]) :Future[T] =
(Future sequence orchestrators.map(poll(_)))
.map(res => res.reduce(implicitly[Semigroup[T]].append(_, _)))
或稍微加糖
def pollAll2[O, T : Semigroup](orchestrators :Seq[O], poll :(O)=>Future[T]) :Future[T] =
(Future traverse orchestrators)(poll(_)).map(_.reduce(_ |+| _))
输出
scala> pollAll(List(1, 2, 3, 4), (i: Int) => Future.successful(i)).foreach(println)
scala> 10
scala> pollAll2(List(1, 2, 3, 4), (i: Int) => Future.successful(i)).foreach(println)
scala> 10