Converting code using simple type projections to dotty

Another approach is type classes and path-dependent types

trait RDF[Rdf <: RDF[Rdf]](using val g: GraphTyp[Rdf], val t: TripleTyp[Rdf], val n: NodeTyp[Rdf]) {
  type Graph = g.Out
  type Triple = t.Out
  type Node = n.Out
}

trait GraphTyp[Rdf <: RDF[Rdf]] {
  type Out
}
object GraphTyp {
  given as GraphTyp[Rdf4j] {
    type Out = Model
  }
}

trait TripleTyp[Rdf <: RDF[Rdf]] {
  type Out
}
object TripleTyp {
  given as TripleTyp[Rdf4j] {
    type Out = Statement
  }
}

trait NodeTyp[Rdf <: RDF[Rdf]] {
  type Out
}
object NodeTyp {
  given as NodeTyp[Rdf4j] {
    type Out = Value
  }
}

trait Rdf4j extends RDF[Rdf4j] 

trait PointedGraph[Rdf <: RDF[Rdf]] {
  def pointer(using n: NodeTyp[Rdf]): n.Out
  def graph(using g: GraphTyp[Rdf]): g.Out
}

In trait RDF I had to replace type member This with type parameter (Rdf) because I needed it in implicit parameters g, t, n of the trait.

1 Like