Search code examples
scalagenericspattern-matchingcase-class

Scala: case classes and pattern matching


I've created this case classes and functions in 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);
}

However it says this when compiling:

[error] test.scala:357: type mismatch; [error] found : test.abc.def.University[B] [error] required: test.abc.def.Building[B]

What am I doing wrong?


Solution

  • University must extend Building[T] not just Building

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

    Here is the complete code

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

    In u function Output type is Building[B]. You are returning University[B] But University[B] takes a which is Building[B] b which is again Building[B] and c which is B.

    n.a returns Building[A] not Building[B] so as University[B] takes two Building[B] and one B. You cannot pass n.a, n.b and n.c to create university[B].

    To make the code compile I have changed the output type and returning 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);
    }
    

    Correct code

    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));
    }