Прежде всего, я не знаю, как правильно пометить мою проблему. Это также может быть причиной того, что я не нашел полезных ресурсов. Любые советы заслуживают высокой оценки.Тип типа и зависимые типы
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]
}
Учитывая приведенный выше код, теперь я могу определить и цепь Rules
S таким образом:
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()
}
Это работает, как я предполагал, но теперь наступает сложная часть. Я хочу ввести Type Class Combination
, в котором объясняется, как присоединиться к двум правилам.
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]
Этот класс класса теперь должен передаваться с операторами.
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)
}
Это еще работает после некоторых настроек.
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()
Но если это усложняется, все разваливается.
A() and B() and A()
Поднимем неявную ошибку недостающий: Combination[and[A, B], A]
отсутствует. Но я хочу, чтобы он использовал результат неявной комбинации and[A, B]
(type Result = MyRule
), который он уже знает, как обращаться (Combination[and[A, B]#Result, A]
).
Для меня важно хранить информацию о комбинированных правилах val x: A and B or A
, сворачивая их вместе с конечным типом результата, но это не то, что я хочу.
Это как можно ближе, но это не скомпилировано.
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()
}
Какую версию Scala вы используете и какую IDE? – eliasah
2.11.6 с IntelliJ, скомпилирование через консоль sbt, хотя – Taig