scala中隐式参数的泛型类型的隐式值

时间:2014-02-27 17:28:36

标签: scala generics implicit

我有一个方法:

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

上述方法不起作用,因为隐式转换使用隐式方法,在查找隐式参数时不考虑它们的结果。

1 个答案:

答案 0 :(得分:0)

我也没有发现您的解决方案有任何问题,但是scalaz定义了名为SemigroupMonoid的类型,可以帮助您。它还包含许多常见类型的Semigroup个定义,例如ListIntSemiGroup定义了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