Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

calling reduce on list of akka http routes yields compilation error (no implicit value for parameter join)

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!

like image 808
evandor Avatar asked Nov 07 '22 15:11

evandor


1 Answers

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 PathMatchers types in your routeDef list.


If you are willing to use shapeless you can then work on heterogeneous lists (called HLists 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)
like image 154
Federico Pellegatta Avatar answered Nov 14 '22 21:11

Federico Pellegatta