2017-10-17 200 views
4

鉴于以下途径呼吁减少对阿卡HTTP路线名单产生编译错误(参数没有隐含价值加入)

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 [元组[字符串]])。

但是编程方式创建,如路线

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

将无法​​编译,给我

找不到参数内含价值加盟:akka.http.scaladsl.server.util.TupleOps 。加入[_1,_1]

此外,推断出的类型的resultingRoute是

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

我真的很感激任何提示给我一些迹象,说明我在这里做错了什么或者如何解决这个问题。

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

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

非常感谢!

+0

'routeDef'在哪里定义? –

+0

更新了添加routeDef赋值的问题,谢谢! – evandor

回答

1

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

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


如果您愿意使用shapeless那么你就可以在异构名单(行话叫HList S IN此背景下)轻松:

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) 
+0

你的回答鼓励我尝试另一种尝试,但我无法创建隐式的TupleOps.Join值......我想知道这种方法是否可以普遍化,对于这样一个简单的情况已经很困难。我创建了一个测试用例,如果有人有(其他)想法:https://gist.github.com/evandor/075cad445712a1144f3d55744516eceb。如果这不适用于(更多)通用方法,那么以这种方式进行并不合适... – evandor

+0

已更新回答,以添加关于如何使用无形状来管理异构列表的建议(以及示例)并使用'reduceLeft'。 –

0

减少表达式有几个问题。

1.减少&关联性

通过使用reduce,而不是reduceLeftreduceRight,你是说

(a/b)/c === a/(b/c) 

因为一个简单的减少并没有给出任何确定性的顺序。我不认为路径匹配器组合是关联的。

2.减少&单位

使用减少的另一个问题是,它是未定义的空单,因此结果总是模棱两可。几乎总是一个更好的选择是reduceOption

+0

你是对的,这是非常有道理的。尽管如此,使用“routeDef.reduceLeftOption((a,b)=> a/b)”或“routeDef.reduceLeft((a,b)=> a/b)”会导致上述编译错误。 – evandor