2017-10-17 282 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

相關問題