Why can't I do this:
def compare[A <% { def toInt: Int },
B <% { def toInt: Int }]
(bs: Seq[A], is: Seq[B]): Boolean = {
bs.toArray.zip(is) forall { p => p._1.toInt == p._2.toInt }
}
In order to compare any Sequence of types convertible to Int
? How can I implement a similar pattern?
Update: this should run Message.compare(List(1.0, 2.0, 3.0), List(0, 0, 0))
Since you're dealing with Array
s, you need ClassManifest
s.
def compare[A <% { def toInt: Int } : ClassManifest,
B <% { def toInt: Int } : ClassManifest]
(bs: Seq[A], is: Seq[B]): Boolean = {
(bs.toArray, is).zipped.forall(_.toInt == _.toInt)
}
The compiler error message in this case couldn't be clearer IMO.
EDIT:
You don't really need to convert sequences to arrays. The following works just fine.
def compare[A <% { def toInt: Int },
B <% { def toInt: Int }]
(bs: Seq[A], is: Seq[B]): Boolean = {
(bs, is).zipped.forall(_.toInt == _.toInt)
}
A good example of where the problem lies would seem to be doing this:
val a = implicitly[Int => { def toInt : Int }]
a(1).toInt
Scala 2.9.1 blows up at this point sometime in Runtime code - I can only think that this is a bug.
You can achieve the effect you're looking for using type classes, though: the following code works in all of your examples:
def compare[A : Numeric, B : Numeric](bs : Seq[A], cs : Seq[B]) = {
(bs, cs).zipped.forall(implicitly[Numeric[A]].toInt(_) == implicitly[Numeric[B]].toInt(_))
}
This should also have the benefit of being faster than the version using structural types. If you need to add your own types in that should be convertible to integers, you can provide evidence for the Numeric typeclass in the same way as is done at https://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_9_1_final/src//library/scala/math/Numeric.scala#L1 for the standard values.
It works fine for me when I remove the unnecessary toArray
def compare[A <% { def toInt: Int }, B <% { def toInt: Int }](bs: Seq[A], is: Seq[B]): Boolean = { bs.zip(is) forall { p => p._1.toInt == p._2.toInt } }
Class A{def toInt = 4}
Class B(i: Int) {def toInt = i}
compare (List(new A, new A), List(new B(3), new B(4))) //false
compare (List(new A, new A), List(new B(4), new B(4))) //true
Converting the Seq to an array would require you add an implicit ClassManifest, however Scala does not let you mix those with view bounds.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With