2017-01-27 14 views
1

Рассмотрим следующие определения:надтипу методов

trait Event 
case class Event1[A] extends Event 
case class Event2[A, B] extends Event 
/* ... */ 

trait Filter { val cond: Event => Boolean } 
case class Filter1[A](cond: Event1[A] => Boolean) extends Filter 
case class Filter2[A, B](cond: Event2[A, B] => Boolean) extends Filter 
/* ... */ 

Я думаю, что это совершенно ясно, что я пытаюсь сделать здесь: Я хочу, чтобы убедиться, что всякий раз, когда я сталкиваюсь с Filter, это гарантированно иметь a cond функция, которая принимает соответствующий подтип Event и дает мне логическое значение. Очевидно, что код выше не компилируется, поскольку, например, Event1[A] => Boolean не является подтипом Event => Boolean. Как решить такую ​​проблему?

ответ

2

Как насчет следующего:

sealed trait Event 
case class Event1[A]() extends Event 
case class Event2[A, B]() extends Event 
/* ... */ 

sealed trait Filter[T <: Event] { val cond: T => Boolean } 
case class Filter1[A](cond: Event1[A] => Boolean) extends Filter[Event1[A]] 
case class Filter2[A, B](cond: Event2[A, B] => Boolean) extends Filter[Event2[A, B]] 

В качестве альтернативы, вы можете переопределить абстрактный тип вместо того, чтобы использовать параметризованные типы:

sealed trait Filter { 
    type Filterable 
    val cond: Filterable => Boolean 
} 
case class Filter1[A](cond : Event1[A] => Boolean) extends Filter{ 
    override type Filterable = Event1[A] 
} 

case class Filter2[A, B](cond: Event2[A, B] => Boolean) extends Filter{ 
    override type Filterable = Event2[A, B] 
} 
0

Попробуйте это:

trait Event 
    case class Event1[A](a: A) extends Event 
    case class Event2[A, B](a: A, b: B) extends Event 

    trait Filter[T <: Event] { val cond: T => Boolean } 
    case class Filter1[A](cond: Event1[A] => Boolean) extends Filter[Event1[A]] 
    case class Filter2[A, B](cond: Event2[A, B] => Boolean) extends Filter[Event2[A, B]] 

Составлен для меня