Допустим, у меня есть следующий:Типа границы и шаблон соответствия в Scala
trait Person {
val name: String
}
case class Student(val name: String) extends Person
case class Teacher(val name: String, students: List[Student]) extends Person
Я хотел бы функцию функции, которая может принимать любые Person
реализацию, матч по определенному типу, а затем возвращать наиболее специфичными type возможно. (Я знаю, что это не может быть умной вещью, но потерпите.) Скажем, что-то вроде:
def teacherGreeting(teacher: Teacher): (Teacher, String) = {
val names = teacher.students.map(_.name).mkString(", ")
(teacher, s"Hello ${teacher.name}, your students are $names")
}
def greet[P <: Person](person: P): (P, String) = person match {
case Student(name) => (person, s"Hello $name")
case Teacher(name, students) => teacherGreeting(person)
}
Но тогда я получаю:
<console>:19: error: type mismatch;
found : P
required: Teacher
case Teacher(name, students) => teacherGreeting(person)
^
Если у меня есть логика teacherGreeting
внутри greet
, у меня нет никаких проблем. Итак, почему компилятор не знает, что P
в этом разделе кода должно быть Teacher
?
Если я использую совпадающее значение:
def greet[P <: Person](person: P): (P, String) = person match {
case Student(name) => (person, s"Hello $name")
case teacher @ Teacher(name, students) => teacherGreeting(teacher)
}
ошибка только происходит позже, с результатом teacherGreeting
, вместо ввода:
error: type mismatch;
found : (Teacher, String)
required: (P, String)
case teacher @ Teacher(name, students) => teacherGreeting(teacher)
^
Неужели нет способа избежать литья?
Спасибо, это очень полезное объяснение! – pr1001