对不同的Functors

时间:2017-10-02 22:35:41

标签: scala functional-programming scala-cats

我一直在尝试使用更抽象的函数编程概念,例如来自scle的typelevel / cats的概念。

在这种特定情况下,我试图消除在遍历一些map(_.flatten)之后调用Future的需要。

使用标准库,它看起来像这样:

def stdExample[T](things: Seq[T]): Future[Seq[T]] = {
  Future.traverse(things)(futureMaybeThings[T]).map(_.flatten)
}
def futureMaybeThings[T](thing: T): Future[Option[T]] = ???

我尝试使用来自typelevel / cats的flatTraverse,但我能得到的最好的是:

def catsExample[T](things: Seq[T]): Future[Seq[T]] = {
  things.toList.flatTraverse(futureMaybeThings[T](_).map(_.toList))
}

要获得Traversable,需要调用things.toList,我可以使用那个。

由于flatTraverse要求fC => G[F[B]]CB都为TG为{ {1}}和FutureF),List在没有先使用futureMaybeThings转换结果的情况下不匹配。这最终比其他解决方案更糟糕。

可以创建一个仅在map(_.toList)Future上运行的函数(因为TraversableOnce存在隐式转换。这样的实现可能是这样的:

Option[A] => TraversableOnce[A]

现在我的工作方式如下:

def flatTraverse[A, B[_], C, M[X] <: TraversableOnceWithFlatten[X, M]](in: M[A])
                                                                (fn: A => Future[B[C]])
                                                                (implicit cbf: CanBuildFrom[M[A], B[C], M[B[C]]],
                                                                 asTraversable: B[C] => TraversableOnce[C],
                                                                 executor: ExecutionContext): Future[M[C]] = {
  Future.traverse(in)(fn).map(_.flatten)
}

有没有办法用typelevel / cats实现同样的事情?

奖金:如果没有,那么这种功能的签名会是什么样的?

0 个答案:

没有答案