Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala: type mismatch error - found T, required String

Tags:

types

scala

I'm learning scala, and this question may be stupid, but... why?

For example, this is ok:

def matchList(ls: List[Int]): List[Int] = ls match {
  case 1 :: rest => rest
  case a :: b :: rest => (a + b) :: rest
  case _ => ls
}

matchList: (ls: List[Int])List[Int]

But function with type parameter does not compile:

def matchList[T](ls: List[T]): List[T] = ls match {
  case 1 :: rest => rest
  case a :: b :: rest => (a + b) :: rest
  case _ => ls
}

<console>:10: error: type mismatch;
found   : T
required: String
   case a :: b :: rest => (a + b) :: rest

Why?

like image 706
dmitry Avatar asked Dec 09 '22 03:12

dmitry


1 Answers

For any type T the operation T + T doesn't make any sense. (Do all types support +? No. Think of adding two dogs or two employees.)

In your case, the string concatenation operator is getting invoked (added via any2stringadd pimp), whose return type is (obviously) String. Hence the error message.

What you need is a way to specify that type T must support an operation where you combine two values of type T to yield a new value of type T. Scalaz's Semigroup fits the bill perfectly.

The following works:

def matchList[T : Semigroup](ls: List[T]): List[T] = ls match {
  case 1 :: rest => rest
  case a :: b :: rest => (a |+| b) :: rest // |+| is a generic 'combining' operator
  case _ => ls
}
like image 69
missingfaktor Avatar answered Dec 25 '22 07:12

missingfaktor