给出以下路线

val route1: PathMatcher[Unit] = PathMatcher("app")
val route2: PathMatcher1[String] = PathMatchers.Segment
val route3: PathMatcher[Unit] = PathMatcher("lastSegment")


我可以轻松定义

val resultingRoute: PathMatcher[Tuple1[String]] = route1 / route2 / route3


获取预期的类型(PathMatcher [Tuple [String]])。

但是像这样在程序中创建路线

val routeDef = List(route1, route2, route3)
val resultingRoute = routeDef.reduce((a,b) => a / b)


不会编译,给我


找不到参数联接的隐式值:akka.http.scaladsl.server.util.TupleOps.Join [_1,_1]


此外,导致的Route的推断类型为

PathMatcher[_ >: Unit with Tuple1[String] with join.Out]


我非常感谢任何提示,这些提示给了我一些提示,说明我在这里做错了什么或如何解决。

为了完整起见,这是我的进口商品:

import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{PathMatcher, _}


非常感谢!

最佳答案

您的问题是您的routeDef列表实际上是异构的,编译器将其类型推断为List[PathMatcher[_ >: Tuple1[String] with Unit]]

鉴于此,(a: PathMatcher[L])./(b: PathMatcher[R])方法隐式需要一个TupleOps.Join[L, R]akka.http.scaladsl.server.PathMatcher。无法从PathMatcher列表中的routeDef类型推断出来。



如果您愿意使用shapeless,则可以轻松地处理异构列表(在这种情况下称为HList):

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)

07-26 03:25