Zunächst einmal weiß ich nicht, wie ich mein Problem richtig beschreibe. Dies könnte auch der Grund sein, warum ich keine hilfreichen Ressourcen gefunden habe. Alle Hinweise werden sehr geschätzt.Typklasse und abhängige Typen
trait Context[T]
{
self =>
trait Rule
{
def apply(value: T): Boolean
}
implicit class RichRule[A <: Rule](a: A)
{
def and[B <: Rule](b: B): and[A, B] = self.and(a, b)
def or[B <: Rule](b: B): or[A, B] = self.or(a, b)
}
sealed trait Group[A <: Rule, B <: Rule] extends Rule
{
def a: A
def b: B
override def apply(value: T) = ???
}
case class and[A <: Rule, B <: Rule](a: A, b: B) extends Group[A, B]
case class or[A <: Rule, B <: Rule](a: A, b: B) extends Group[A, B]
}
den obigen Code gegeben, kann ich jetzt definieren und Kette Rules
s in dieser Art und Weise:
new Context[String]
{
class MyRule extends Rule
{
override def apply(value: String) = true
}
case class A() extends MyRule
case class B() extends MyRule
val x1: A and B or A = A() and B() or A()
}
Das funktioniert, wie ich kommt bestimmt aber jetzt ist der schwierige Teil. Ich möchte eine Typklasse Combination
vorstellen, die erklärt, wie man zwei Regeln verbindet.
trait Combination[-A <: Rule, -B <: Rule]
{
type Result <: Rule
def combine(a: A, b: B): Result
}
trait AndCombination[-A <: Rule, -B <: Rule] extends Combination[A, B]
trait OrCombination[-A <: Rule, -B <: Rule] extends Combination[A, B]
Diese Typklasse sollte jetzt mit den Operatoren übergeben werden.
implicit class RichRule[A <: Rule](a: A)
{
def and[B <: Rule](b: B)(implicit c: AndCombination[A, B]): and[A, B] = ???
def or[B <: Rule](b: B)(implicit c: OrCombination[A, B]): or[A, B] = self.or(a, b)
}
Das funktioniert immer noch nach einigen Verbesserungen.
implicit val c1 = new Combination[MyRule, MyRule]
{
type Result = MyRule
def combine(a: A, b: B): MyRule = a
}
val x: A and B = A() and B()
Aber wenn es komplizierter wird, fallen die Dinge auseinander.
A() and B() and A()
Wird ein impliziten fehlenden Fehler aus: Combination[and[A, B], A]
fehlen. Aber ich möchte, dass es das Ergebnis der impliziten Kombination von and[A, B]
(type Result = MyRule
) verwendet, die es bereits versteht (Combination[and[A, B]#Result, A]
).
Es ist wichtig für mich, die Typinformationen der kombinierten Regeln val x: A and B or A
zu behalten, sie zu einem Endergebnis zusammenzufalten ist einfach, aber nicht was ich will.
Das ist so nah wie möglich, aber es kompiliert nicht.
trait Context[T]
{
self =>
trait Rule
trait Value extends Rule
trait Group[A <: Rule, B <: Rule] extends Rule
{
def a: A
def b: B
implicit val resolver: Resolver[_ <: Group[A, B]]
}
case class and[A <: Rule, B <: Rule](a: A, b: B)(implicit val resolver: Resolver[and[A, B]]) extends Group[A, B]
implicit class RichRule[A <: Rule](a: A)
{
def and[B <: Rule](b: B)(implicit resolver: Resolver[and[A, B]]) = self.and[A, B](a, b)
}
trait Resolver[-A <: Rule]
{
type R <: Value
def resolve(a: A): R
}
}
object O extends Context[String]
{
implicit val c1 = new Resolver[A and A]
{
override type R = A
override def resolve(a: O.and[A, A]) = ???
}
implicit def c2[A <: Value, B <: Value, C <: Value](implicit r1: Resolver[A and B]) = new Resolver[A and B and C]
{
override type R = C
override def resolve(a: A and B and C): C =
{
val x: r1.R = r1.resolve(a.a)
new c2(x)
???
}
}
class c2[A <: Value, B <: Value](val a: A)(implicit r2: Resolver[A and B]) extends Resolver[A and B]
{
override type R = B
override def resolve(a: O.and[A, B]) = a.b
}
case class A() extends Value
val x: A and A and A = A() and A() and A()
}
zu lösen Welche Version von Scala verwenden Sie und welche IDE? – eliasah
2.11.6 mit IntelliJ, kompiliert über sbt Konsole obwohl – Taig