Я пытаюсь преобразовать произвольный HList в Future [HList], где все элементы Future сведены.
Например:
- Превратить
Int :: Future[String] :: HNil
в Future[Int :: String :: HNil]
- Превратить
Future[Boolean] :: String :: Int :: HNil
в Future[Boolean :: String :: Int :: HNil]
До сих пор мне удавалось реализовать преобразование HList of Futures в Future их результатов, используя foldRight
.
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
теперь имеет конфликтующие случаи, так как элементы HList типа Future соответствуют и future
и default
case.
Моя цель состояла в том, чтобы сопоставить любой элемент , кроме Futures, но, очевидно, компилятор не может вывести это из приведенного выше кода.
Возможно ли это добиться этого преобразования, используя foldRight
вообще? Как?