Scala: классы прецедентов и сопоставление с образцом

#scala #generics #pattern-matching #case-class

#scala #дженерики #сопоставление с образцом #case-класс

Вопрос:

Я создал классы и функции этого случая в scala:

 abstract class Building[T]
case class University[T](a: Building[T], b: Building[T], c: T) extends Building

def u[A,B](a: Building[A]): Building[B] = a match {
  case n: University[A] => University[B](n.a, n.b, n.c);
}
 

Однако это говорит об этом при компиляции:

[ошибка] test.scala:357: несоответствие типов; [ошибка] найдено: test.abc.def.University[B] [ошибка] требуется: test.abc.def.Building[B]

Что я делаю не так?

Ответ №1:

University должно расширяться Building[T] не только Building

 case class University[T](a: Building[T], b: Building[T], c: T) extends Building[T]
 

Вот полный код

 abstract class Building[T]
case class University[T](a: Building[T], b: Building[T], c: T) extends Building[T]
 

В u функции тип вывода Building[B] равен . Вы возвращаетесь University[B] , но University[B] принимаете a, который является Building[B] b, который снова Building[B] и c который есть B .

n.a возвращает Building[A] не Building[B] так, как University[B] принимает два Building[B] и один B . Вы не можете передавать n.a n.b и n.c создавать university[B] .

Чтобы заставить код компилироваться, я изменил тип вывода и вернул University[B]

 def u[A,B](a: Building[A]): Building[A] = a match {
  case n: University[A] => University[A](n.a, n.b, n.c);
}
 

Правильный код

 abstract class Building[T]

case class University[T](a: Building[T], b: Building[T], c: T) extends Building[T]

def convert[A, B](a: A): B = ???

def bConvert[A, B](building: Building[A]): Building[B] = ???

def u[A,B](a: Building[A]): Building[B] = a match {
  case n: University[A] => University[B](bConvert(n.a), bConvert(n.b), convert(n.c));
}