monica
monica

Reputation: 1065

Why the two apply methods in companion objects do not work?

I have two apply methods defined in companion object PS, assumed that could be the syntax desuger, but when I try to instantiate the PS, errors shown ( inlined in code) are confusing for me:

package tests
import scala.collection.immutable.TreeSet
import scala.collection.immutable.SortedSet



object TestCompanionApply {

  val members = List(2,3,5,7)

  /**
   *  error for the next line:
    type mismatch;  found   : <:<[Nothing,Nothing]  required: A => tests.PH with Ordered[A] 

   */
  val ps1 = PS()


  /**
   * The two errors for the next line: 
   * 
     No implicit view available from Int => tests.PH with Ordered[Int].

     not enough arguments for method apply: (implicit evidence$3: Int => tests.PH with Ordered[Int])tests.PS[Int] in object PS. 
    Unspecified value parameter evidence$3. 

   */
  val ps = PS(members: _*)

}

 class PS[A <% PH with Ordered[A]] 
(val comp : BigInt, val members : SortedSet[A]) {
  def + (a : A) : PS[A] = {
    val h = a.pH
    if (comp % h == 0) {
      this
    } else {
      new PS[A](comp * h, members + a)
    }
  }


  override def hashCode() : Int = comp.hashCode()
  override def equals (o : Any) = o match {
    case a : PS[_] => a.comp == comp
  }

  override def toString = members.toString
}

trait PH {
  def pH : BigInt  
}


object PS {
  def apply[A <% PH with Ordered[A]] () =
    new PS(1, TreeSet[A]())

  def apply[A <% PH with Ordered[A]] (vals : A*) = 
    new PS[A](vals.foldLeft (BigInt(1)) ((ans,v) => ans * v.pH),TreeSet[A]() ++ vals.toList)
}

Upvotes: 0

Views: 255

Answers (1)

michael_s
michael_s

Reputation: 2575

The second error indicates, that there is no implicit conversion from Int to test.PH with Ordered[Int]. In that case you could simply provide an implicit conversion yourself in TestCompanionApply, like this:

implicit def intToPH(i: Int) = new PH with Ordered[Int]{
  val pH: BigInt = i
  def compare(that: Int) = pH.toInt - that
}

Or instead of doing it implicitly doing it explicitly (defining some new PH with Ordered on the right hand side).

and for val ps1 = PS() the compiler cannot infer any type arguments. I guess in your case you maybe mean int? So with the above implicit conversion you will get a compilation success when you define ps1 with:

val ps1 = PS[Int]()

However I'm not exactly sure if that does what you want.

Upvotes: 2

Related Questions