Shapeless and gremlin scala: How do I return the result of a call to `as`?

☆樱花仙子☆ 提交于 2019-12-11 04:09:56

问题


So, I am calling this function as (from 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: _*))
}

It is defined here: https://github.com/mpollmeier/gremlin-scala/blob/master/gremlin-scala/src/main/scala/gremlin/scala/GremlinScala.scala#L239

It takes an implicit Prepend argument, which I am not sure I understand. I know that gremlin-scala uses its HList to keep track of which points in the query as is called, so that later when select is called it knows which points in the traversal to return.

This is the key: as appends to that HList. Or prepends apparently, as the case may be.

This works fine in general code, but now I want to write a function that calls as and returns its result. This is where I am stuck: what is the signature of the return value of this function?

Finally, I have added an implicit param to my function, but I fear I have just chased the problem up a level. Here is what I have so far:

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

This makes it compile, but I still can't use this function! Whenever I call it, it complains to me that

could not find implicit value for parameter p: shapeless.ops.hlist.Prepend[In,shapeless.::[A,shapeless.HNil]]

How do I write a function that returns the result of as, and what is its signature?

Thanks!


回答1:


As you explain correctly, the reason we use prepend is to keep the types of the steps labelled with as. It's keeping them in the reverse order since it's easier to process on both sides: for capturing and replaying.

So the implicit p: Prepend[Labels, End :: HNil] is prepending the type at the current step so that we have it captured in the second type parameter (and can use it in later steps, e.g. select).

As far as I can see you're doing exactly the right thing, and it actually works... for me anyway :)

This compiles:

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


来源:https://stackoverflow.com/questions/40601888/shapeless-and-gremlin-scala-how-do-i-return-the-result-of-a-call-to-as

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!