简体   繁体   English

如何链接路由(使用`~`)是函数的结果?

[英]How do I chain routes (using `~`) which are the results of functions?

scala> import akka.http.scaladsl.server._; import Directives._
import akka.http.scaladsl.server._
import Directives._

Suppose I have two functions from some type ( Int , say) to a Route : 假设我有一些类型( Int ,比如说)到Route两个函数:

scala> lazy val r1: Int => Route = ???
r1: Int => akka.http.scaladsl.server.Route = <lazy>

scala> lazy val r2: Int => Route = ???
r2: Int => akka.http.scaladsl.server.Route = <lazy>

I can compose a route thusly: 我可以这样写一条路线:

scala> lazy val composite: Route = path("foo"){ r1(1) } ~ path("bar"){ r2(1) }
composite: akka.http.scaladsl.server.Route = <lazy>

What I would like to do is use function composition together with the ~ path chaining. 我想要做的是使用函数组合和~ path链接。 That is, I'd love for this to just work: 也就是说,我喜欢这个工作:

scala> lazy val composite: Int => Route = path("foo")(r1) ~ path("bar")(r2)

Except it doesn't :-( 除了它没有:-(

<console>:31: error: type mismatch;
 found   : Int => akka.http.scaladsl.server.Route
    (which expands to)  Int => (akka.http.scaladsl.server.RequestContext => scala.concurrent.Future[akka.http.scaladsl.server.RouteResult])
 required: akka.http.scaladsl.server.Route
    (which expands to)  akka.http.scaladsl.server.RequestContext => scala.concurrent.Future[akka.http.scaladsl.server.RouteResult]
       lazy val composite: Int => Route = path("foo")(r1) ~ path("bar")(r2)
                                                      ^

EDIT 编辑

I am trying to do this using point-free function composition,. 我试图使用无点函数组合来做到这一点。 As Ramon 's answer below demonstrates, it's easy to do this if you are willing to duplicate the function application (but this is what I want to avoid). 正如拉蒙在下面的回答所示,如果你愿意复制函数应用程序,这很容易做到(但这是我想要避免的)。 That is: 那是:

lazy val composite: Int => Route 
  = i => path("foo")(r1(i)) ~ path("bar")(r2(i))

NOTE 注意

Using scalaz , I can do this: 使用scalaz ,我可以这样做:

scala> import akka.http.scaladsl.server._; import Directives._; import scalaz.syntax.monad._; import scalaz.std.function._
import akka.http.scaladsl.server._
import Directives._
import scalaz.syntax.monad._
import scalaz.std.function._

scala> lazy val r1: Int => Route = ???
r1: Int => akka.http.scaladsl.server.Route = <lazy>

scala> lazy val r2: Int => Route = ???
r2: Int => akka.http.scaladsl.server.Route = <lazy>

scala> lazy val composite = for (x <- r1; y <- r2) yield path("foo")(x) ~ path("bar")(y)
composite: Int => akka.http.scaladsl.server.Route = <lazy>

Which is so good as it goes but the implicit ConjunctionMagnet.fromRouteGenerator in akka.http.scaladsl.server gives me cause to think it might be possible in akka-http directly 这是如此的好,但akka.http.scaladsl.server的隐式ConjunctionMagnet.fromRouteGenerator让我有理由认为它可能直接在akka-http中

The equivalent to the scalaz example you gave is: 相当于你给出的scalaz示例是:

lazy val composite: Int => Route = 
  (i) => path("foo")(r1(i)) ~ path("bar")(r2(i))

Similarly, you could anonymize the parameter name but that would result in 2 parameters: 同样,您可以匿名参数名称,但这会产生2个参数:

lazy val composite: (Int,Int) => Route = path("foo")(r1(_)) ~ path("bar")(r2(_))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM