Shapeless и gremlin scala: как вернуть результат вызова в `as`?
Итак, я вызываю эту функцию as
(от gremlin-scala
):
case class GremlinScala[End, Labels <: HList](traversal: GraphTraversal[_, End]) {
def as(name: String, moreNames: String*)(implicit p: Prepend[Labels, End :: HNil]) =
GremlinScala[End, p.Out](traversal.as(name, moreNames: _*))
}
Это определяется здесь: https://github.com/mpollmeier/gremlin-scala/blob/master/gremlin-scala/src/main/scala/gremlin/scala/GremlinScala.scala
Требуется неявный аргумент Prepend, который я не уверен, что понимаю. я знаю это gremlin-scala
использует свой HList, чтобы отслеживать, какие точки в запросе as
называется, так что позже, когда select
называется он знает, какие точки в обходе, чтобы вернуться.
Это ключ: as
добавляет к этому HList. Или, видимо, претендует, в зависимости от обстоятельств.
Это нормально работает в общем коде, но теперь я хочу написать функцию, которая вызывает as
и возвращает свой результат. Вот где я застрял: что является сигнатурой возвращаемого значения этой функции?
Наконец, я добавил в свою функцию неявный параметр, но боюсь, что только что преследовал проблему до уровня. Вот что у меня так далеко:
case class AsOperation[A, In <: HList](step: String) extends Operation {
def operate(g: GremlinScala[A, In]) (implicit p: Prepend[In, ::[A, HNil]]): GremlinScala[A, p.Out] = {
g.as(step)
}
}
Это делает его компиляцией, но я все еще не могу использовать эту функцию! Всякий раз, когда я это называю, мне жалуется, что
could not find implicit value for parameter p: shapeless.ops.hlist.Prepend[In,shapeless.::[A,shapeless.HNil]]
Как мне написать функцию, которая возвращает результат as
и какая у него подпись?
Спасибо!
1 ответ
Как вы правильно объясните, причина, по которой мы используем prepend, состоит в том, чтобы сохранить типы шагов, помеченные как as
, Он держит их в обратном порядке, поскольку его легче обрабатывать с обеих сторон: для захвата и воспроизведения.
Итак implicit p: Prepend[Labels, End :: HNil]
на текущем шаге добавляется тип, чтобы он был захвачен во втором параметре типа (и мы можем использовать его на последующих шагах, например, select
).
Насколько я вижу, ты делаешь совершенно правильные вещи, и это на самом деле работает... в любом случае для меня:)
Это компилирует:
import gremlin.scala._
import shapeless.{HNil, ::}
import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerFactory
def graph = TinkerFactory.createModern.asScala
val gs1: GremlinScala[Vertex, Vertex :: HNil] = graph.V().as("a")
val gs2: GremlinScala[Vertex, Vertex :: HNil] = AsOperation("someLabel").operate(graph.V())