私が次のものを持っているとしましょう:
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
、特定の型に一致し、可能な限り最も具体的な型を返す関数関数が欲しいです。(これは賢明なことではないかもしれませんが、ご了承ください。) 次のように言いましょう。
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)
^
キャストを避ける方法はありませんか?