Given the following routes
val route1: PathMatcher[Unit] = PathMatcher("app")
val route2: PathMatcher1[String] = PathMatchers.Segment
val route3: PathMatcher[Unit] = PathMatcher("lastSegment")
I can easily define
val resultingRoute: PathMatcher[Tuple1[String]] = route1 / route2 / route3
getting the expected type (PathMatcher[Tuple[String]]).
But creating the route programmatically like in
val routeDef = List(route1, route2, route3)
val resultingRoute = routeDef.reduce((a,b) => a / b)
will not compile, giving me
could not find implicit value for parameter join: akka.http.scaladsl.server.util.TupleOps.Join[_1,_1]
Furthermore, the inferred type of resultingRoute is
PathMatcher[_ >: Unit with Tuple1[String] with join.Out]
I'd really appreciate any hint giving me some indication of what I'm doing wrong here or how this could be resolved.
For completeness, here's my imports:
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{PathMatcher, _}
Thanks so much!
Your problem is that your routeDef
list is actually heterogeneous, the compiler infers its type to be List[PathMatcher[_ >: Tuple1[String] with Unit]]
.
Given that, the (a: PathMatcher[L])./(b: PathMatcher[R])
method needs implicitly a TupleOps.Join[L, R]
: akka.http.scaladsl.server.PathMatcher. It cannot be inferred from PathMatcher
s types in your routeDef
list.
If you are willing to use shapeless
you can then work on heterogeneous lists (called HList
s in this context) easily:
import shapeless._
val routeDef = route1 :: route2 :: route3 :: HNil
object join extends Poly {
implicit def casePathMatcher[A, B](
implicit t: akka.http.scaladsl.server.util.TupleOps.Join[A,B]
) = use((a: PathMatcher[A], b: PathMatcher[B]) => a/b)
}
val resultingRoute: PathMatcher[Tuple1[String]] = routeDef.reduceLeft(join)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With