键入具有更高kinded类型和含义的分辨率

时间:2014-10-28 23:25:26

标签: scala scalaz

我正在尝试编写一个Value Class来为实现Seq[_]的任何东西添加功能,并允许它进行返回Future[_]的批量调用(具体来说,我用它来进行批量REST调用) )。

final class BatchedList[A, C[X] <: Seq[X]](val targetList: C[A]) extends AnyVal {

  def batchRequests[B](batchSize: Int)(runner: Seq[A] => Seq[Future[Either[Result, B]]])
    (implicit bf: CanBuildFrom[C[A], Either[Result, B], C[Either[Result, B]]]): Future[Either[Result, C[B]]] = {
      targetList.grouped(batchSize).foldLeft(Future.successful(bf(targetList))) { (results, set) =>
        results flatMap { responses =>
          Future.sequence(runner(set)).map(responses ++=)
        }
      } map {
        _.result().sequenceU
      }
    }
  }

但是,我无法编译。我一直收到编译错误

value sequenceU is not a member of type parameter C[Either[play.api.mvc.Result,B]]

我已导入scalaz._Scalaz._,我知道他们为我的用例Traverse[_]提供了List[_]这个例子)。我很确定这是类型的某种隐式解决问题,但我很难理解如何继续解决它。

1 个答案:

答案 0 :(得分:1)

我认为这是因为Scalaz不为Seq提供类型类实例,而是为IndexedSeqList提供类型实例。因此,您需要自己提供Traverse实例(请注意C的其他隐式参数batchRequests):

final class BatchedList[A, C[X] <: Seq[X]](val targetList: C[A]) extends AnyVal {
  def batchRequests[B](batchSize: Int)(runner: Seq[A] => Seq[Future[Either[Result, B]]])
    (implicit bf: CanBuildFrom[C[A], Either[Result, B], C[Either[Result, B]]], C: Traverse[C]): Future[Either[Result, C[B]]] =
      targetList.grouped(batchSize).foldLeft(Future.successful(bf(targetList))) { (results, set) =>
        results flatMap { responses =>
          Future.sequence(runner(set)).map(responses ++=)
        }
      } map {
        _.result().sequenceU
      }
}

如您所见,这将返回与C提供的类型对应的序列类型:

scala> def run[A](s: Seq[A]): Seq[Future[Either[Result, A]]] =
     |   s.map(i => Future.successful(Right(i)))
run: [A](s: Seq[A])Seq[scala.concurrent.Future[Either[Result,A]]]

scala> :t new BatchedList(List(1,2,3)).batchRequests(1)(run)
scala.concurrent.Future[Either[Result,List[Int]]]

scala> :t new BatchedList(Vector(1,2,3)).batchRequests(1)(run)
scala.concurrent.Future[Either[Result,scala.collection.immutable.Vector[Int]]]

如果你总是希望它返回一个Seq,这只是一个简单的问题。