Как мне связать маршруты (используя `~`), которые являются результатами функций?

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

Предположим, у меня есть две функции из некоторого типа (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>

Я могу составить маршрут так:

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

То, что я хотел бы сделать, это использовать композицию функций вместе с ~ цепочка путей. То есть я бы хотел, чтобы это просто работало

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

За исключением того, что это не так:-(

<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)
                                                      ^

РЕДАКТИРОВАТЬ

Я пытаюсь сделать это, используя бессмысленную композицию функций. Как показывает приведенный ниже ответ Рамона, это легко сделать, если вы захотите продублировать приложение-функцию (но этого я и хочу избежать). То есть:

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

НОТА

Используя скалаз, я могу сделать это:

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>

Который так хорош, но неявный ConjunctionMagnet.fromRouteGenerator в akka.http.scaladsl.server дает мне повод думать, что это возможно в Акка-http напрямую

1 ответ

Эквивалент приведенного вами примера скаляза:

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

Точно так же вы можете анонимизировать имя параметра, но это приведет к 2 параметрам:

lazy val composite: (Int,Int) => Route = path("foo")(r1(_)) ~ path("bar")(r2(_))
Другие вопросы по тегам