【发布时间】:2020-04-05 01:37:14
【问题描述】:
我正在尝试将任意 HList 转换为 Future[HList],其中所有 Future 元素都被展平。
例如:
- 把
Int :: Future[String] :: HNil变成Future[Int :: String :: HNil] - 把
Future[Boolean] :: String :: Int :: HNil变成Future[Boolean :: String :: Int :: HNil]
到目前为止,我已经能够使用 foldRight 将一个 HList of Futures 转换为他们的结果的 Future。
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, ExecutionContext, Future}
import shapeless._
object joinFutures extends Poly2 {
implicit def future[L, R <: HList](implicit ec: ExecutionContext): Case[Future[L], Future[R]] {
type Result = Future[L :: R]
} = at[Future[L], Future[R]] { (futureL, futureR) =>
futureR.flatMap(r => futureL.map(_ :: r))
}
}
object Example extends App {
import ExecutionContext.Implicits.global
import Future.{successful => F}
type In = Future[Int] :: Future[String] :: Future[Int] :: Future[String] :: HNil
type Out = Future[Int :: String :: Int :: String :: HNil]
val in: In = F(1) :: F("asd") :: F(2) :: F("qwe") :: HNil
val out: Out = in.foldRight(Future.successful(HNil))(joinFutures)
println(Await.result(out, Duration.Inf)) // 1 :: asd :: 2 :: qwe :: HNil
}
然后我尝试在我的 Poly2 中引入默认情况,对于所有其他情况。
object joinFutures extends Poly2 {
implicit def future[L, R <: HList](implicit ec: ExecutionContext): Case[Future[L], Future[R]] {
type Result = Future[L :: R]
} = at[Future[L], Future[R]] { (lFuture, futureR) =>
futureR.flatMap(r => lFuture.map(_ :: r))
}
implicit def default[L, R <: HList](implicit ec: ExecutionContext): Case[L, Future[R]] {
type Result = Future[L :: R]
} = at[L, Future[R]] { (l, futureR) =>
futureR.map(r => l :: r)
}
}
但是在调用 foldRight 时编译失败并出现错误,指出它找不到文件夹 RightFolder[In,Future[HNil.type],joinFutures.type] 的隐式。
我想问题是 joinFutures 现在有冲突的情况,因为 Future 类型的 HList 元素匹配 future 和 default 情况。
我的目标是匹配任何元素 except 期货,但显然编译器无法从上面的代码中推断出来。
是否有可能使用foldRight 来实现这种转换?怎么样?
【问题讨论】: