ste*_*bot 7 functional-programming scala scala-cats
我一直在尝试使用更抽象的函数式编程概念,例如来自scle的typelevel/cats的概念.
在这个特定的情况下,我试图消除map(_.flatten)
遍历一些Future
s 后调用的需要.
使用标准库,它看起来像这样:
def stdExample[T](things: Seq[T]): Future[Seq[T]] = {
Future.traverse(things)(futureMaybeThings[T]).map(_.flatten)
}
def futureMaybeThings[T](thing: T): Future[Option[T]] = ???
Run Code Online (Sandbox Code Playgroud)
我尝试使用flatTraverse
typelevel/cats,但我能得到的最好的是:
def catsExample[T](things: Seq[T]): Future[Seq[T]] = {
things.toList.flatTraverse(futureMaybeThings[T](_).map(_.toList))
}
Run Code Online (Sandbox Code Playgroud)
things.toList
要求获得Traversable需要调用,我可以使用那个.
由于flatTraverse
需要f
为C => G[F[B]]
(其中两个C
和B
是T
,G
是Future
和F
是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)
}
Run Code Online (Sandbox Code Playgroud)
这现在符合我的要求:
def customExample[T](things: Seq[T]): Future[Seq[T]] = {
flatTraverse(things)(futureMaybeThings[T])
}
Run Code Online (Sandbox Code Playgroud)
有没有办法用typelevel/cats实现同样的事情?
奖励:如果没有,那么这种功能的签名是什么样的?