Scala REPL “error: value > is not a member of type

2019-02-18 05:46发布

This is my file

trait Set[T] {
    def contains(x: T): Boolean
    def incl(x: T): Set[T]
    def union(that: Set[T]): Set[T]
}

class Empty[T] extends Set[T] {
    override def toString = "."
    def contains(x: T): Boolean = false
    def incl(x: T): Set[T] = new NonEmpty[T](x, new Empty[T], new Empty[T])
    def union(that: Set[T]): Set[T] = that
}

class NonEmpty[T](elem: T, left: Set[T], right: Set[T]) extends Set[T] {
    override def toString = "{" + left + elem + right + "}"

    def contains(x: T): Boolean =
        if (x < elem) left contains x
        else if (x > elem) right contains x
        else true

    def incl(x: T): Set[T] =
         if (x < elem) new NonEmpty(elem, left incl x, right)
         else if (x > elem) new NonEmpty(elem, left, right incl x)
         else this

    def union(that: Set[T]): Set[T] =
        ((left union right) union that) incl elem
}

I'm using the ":paste" method because :load doesn't work. But I get the following error

<console>:25: error: value < is not a member of type parameter T
               if (x < elem) left contains x
                     ^
<console>:26: error: value > is not a member of type parameter T
               else if (x > elem) right contains x
                          ^
<console>:30: error: value < is not a member of type parameter T
                if (x < elem) new NonEmpty(elem, left incl x, right)
                      ^
<console>:31: error: value > is not a member of type parameter T
                else if (x > elem) new NonEmpty(elem, left, right incl x)

I'm sure this file is correct, because it is from class examples, and it worked in class when Prof. is using...

Any helps?

2条回答
甜甜的少女心
2楼-- · 2019-02-18 06:09

You get that error because not every type T has >,< etc. defined.

What you probably wanted is T to be Ordered or be implicitly convertible to something that is Ordered , and therefore have all of them defined.

This should fix the error messages:

class NonEmpty[T <% Ordered[T]](elem: T, left: Set[T], right: Set[T]) extends Set[T] {
    override def toString = "{" + left + elem + right + "}"

    def contains(x: T): Boolean =
        if (x < elem) left contains x
        else if (x > elem) right contains x
        else true

    def incl(x: T): Set[T] =
        if (x < elem) new NonEmpty(elem, left incl x, right)
        else if (x > elem) new NonEmpty(elem, left, right incl x)
        else this

    def union(that: Set[T]): Set[T] =
        ((left union right) union that) incl elem
}

T <% S (a view bound) says that type T must be convertible to S, so it has to be either a subtype of S or have implicit conversion defined.

Accepter answer to this queston explains it in more detail.

查看更多
干净又极端
3楼-- · 2019-02-18 06:15

Since "view bounds" have been deprecated in Scala 2.11, an alternative implementation of a generic Binary Search Tree using "context bounds" is below:

object GenericBinarySearchTree {

abstract class Set[T] {
  def incl(x: T): Set[T]
  def contains(x: T): Boolean
  def union(that: Set[T]): Set[T]
}

type L[X] = X => Ordered[X]

class Empty[T : L] extends Set[T] {

  override def toString = "."

  def incl(x: T): Set[T] = new NonEmpty(x, new Empty, new Empty)

  def contains(x: T): Boolean = false

  def union(that: Set[T]): Set[T] = that
}

class NonEmpty[T : L](elem: T, left: Set[T], right: Set[T]) extends Set[T] {  

  override def toString = "{" + left + elem + right + "}"

  def incl(x: T): Set[T] = {
    if(x > elem) new NonEmpty(elem, left, right.incl(x))
    else if(x < elem) new NonEmpty(elem, left.incl(x), right)
    else this
  }

  def contains(x: T): Boolean = {
    if(x == elem) true 
    else if(x > elem) right.contains(x)
    else left.contains(x)
  } 

  def union(that: Set[T]): Set[T] = ((left union right) union that) incl elem
}

}
查看更多
登录 后发表回答