0

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.

  • What's the error? – Marth Jun 07 '18 at 20:48
  • @Marth I get 'pattern type is incompatible with expected type, dound: Nil.type, required: List[T]' having Nil at the first case underlined – Yuri Makarevich Jun 07 '18 at 20:51
  • but there's not the only one, could you try it yourself? – Yuri Makarevich Jun 07 '18 at 20:53
  • 1
    You should edit your question to add this. As for the error itself the problem is that `this` (in `this match {}`) is not a `scala.collection.immutable.List` but the `List` class you're currently defining. Your `List[T]` is unrelated to the one defined in scala's stdlib. – Marth Jun 07 '18 at 20:54
  • Thanks, I got it. But could you suggest a way to get the desired result of redefining a stdlib method? – Yuri Makarevich Jun 07 '18 at 20:56
  • @YuriMakarevich your way works, but you need to define `Nil` and `::` for your custom list as well. It's best to use different names though to avoid confusion. – puhlen Jun 07 '18 at 20:58
  • @puhlen if there is a way of redefining the standard method in the List class itself, could you describe it to me please? :) – Yuri Makarevich Jun 07 '18 at 21:10
  • @YuriMakarevich you can't really redefine the preexisting classes. Why do you want to do this? There may be a better way of achieving your goal. – puhlen Jun 08 '18 at 02:09

1 Answers1

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 {
puhlen
  • 8,400
  • 1
  • 16
  • 31
  • can I redefine the standard List method in the List class itself? – Yuri Makarevich Jun 07 '18 at 21:05
  • @YuriMakarevich not really. You could create a wrapper class for list, that just calls to the underlying list for everything except for the methods you want to modify. Or if you really need to modify the List that comes with Scala, you could download the Scala source code, modify the list class, and build yourself a custom version. That's crazy overkill though and almost certainly not needed. – puhlen Jun 08 '18 at 02:08