Why can't I run such scala code? (reduceRight

2019-08-20 20:49发布

问题:

My code:

abstract class List[T] {
  def reduceRight(op: (T, T) => T): Either[String, T] = this match {
    case Nil => Left("reduce on empty list")
    case x => Right(x)
    case x::xs => Right(op(x, xs, reduceRight(op)))
  }
}

My error:

pattern type is incompatible with expected type, dound: Nil.type, required: List[T]

I'm a complete newbie in Scala, so, please, describe your answer.

回答1:

tldr: name your class something else, have the method take in a second parameter which is the List you want to reduce.

The problem is you named your class List which is already the name of a class in Scala. This on it's own is actually not going to break the code, but it can cause some confusion on whether you mean the Scala List or your custom List.

You then confuse it and try to use your custom class as if it were a regular Scala List. in particular trying to use pattern matching with things like Nil and ::. Those only work for the Scala List, not your custom one. You could of course also write the code for those to work with your custom List, but you still need to be careful to make sure which one you are referring too, I would recommend using different names if you go this route.

An easier solution is to name the class something else, then change Reduce right to also take in a regular List as a parameter. Something like this:

abstract class MyClass {
  def reduceRight[T](list: List[T], op: (T, T) => T): Either[String, T] = list match {