Предположим, у меня есть следующий код Scala:Добавить пользовательские компиляции проверяет время в Scala
sealed trait Foo
sealed trait Bar
object Foo1 extends Foo
object Foo2 extends Foo
object Foo3 extends Foo
object Bar1 extends Bar
object Bar2 extends Bar
object Bar3 extends Bar
case class Hello(foo:Foo, bar:Bar)
val a = Hello(Foo1, Bar2) // allowed
val b = Hello(Foo2, Bar2) // suppose not allowed
Мне нужно поймать во время компиляции, если какой-либо несовместимое сочетание применяется к Hello
. Предположим, что допускаются только следующие комбинации: (Foo1, Bar1)
, (Foo1, Bar2)
, (Foo2, Bar3)
и (Foo3, Bar3)
.
Можно ли проверить это во время компиляции? Я понимаю, что plugins и macros могут позволить мне это сделать. Некоторые намеки были бы оценены. Вышеприведенные учебники выглядят устаревшими для последних версий Scala (2.11.x), поэтому указатели на другие учебники также будут отличными.
В реальном примере имеется около 10 экземпляров Foo
и Bar
, что дает в общей сложности 100 комбинаций, около половины из них недействительны. Более того, допустимые комбинации могут в будущем измениться произвольно.
EDIT
Актуальной проблемой является немного более сложным. Метод Hello
принимает Seq
следующим образом:
case class Hello(foos:Seq[Foo], bars:Seq[Bar])
Примеры сложных критериев:
- Если
foos
содержатFoo1
тоbars
не может иметьBar1
. foos
не может содержатьFoo1
иFoo3
вместе.
примеры кода:
Hello(Seq(Foo1), Seq(Bar2, Bar3)) // valid
Hello(Seq(Foo1, Foo3), Seq(Bar1)) // invalid due to rule 2
в дополнение к @ ответ DaunnC, есть это объяснение техники [здесь] (http://www.chuusai.com/2011/07/16/ fundeps-в-Скале /). –
Существуют ли какие-либо правила, которые определяют, какие комбинации действительны, а какие нет? –
@MilesSabin No. Действительные комбинации довольно произвольные .. но есть определенные правила. См. Мое редактирование выше. – Jus12