For example, you'd like to learn about the Seq trait in Scala. So you open the API page of it and find a long list of methods. Let's say you're interested in learning the behaviors of the following methods:
/** Appends all elements of this sequence to a string builder. The written text consists of the string representations (w.r.t. the method toString) of all elements of this sequence without any separator string. */
def addString(b: StringBuilder): StringBuilder
To do that, you issue the "scala" command from a shell/command prompt and then explore the method like:
kent@dragon:~$ scala
Welcome to Scala version 2.8.0.r20327-b20091231020112 (Java HotSpot(TM) Server VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.
scala> val a = List("a", "b", "c")
a: List[Int] = List(a, b, c)
scala> val b = new StringBuilder
b: StringBuilder =
scala> b.append("hi")
res0: StringBuilder = hi
scala> a.addString(b)
res1: StringBuilder = hiabc
From the experiment, it is clear that the addString() method will append all the elements of the Seq to the string builder.
Let's consider another. You're interested in:
/** Multiplies up the elements of this collection. num is an implicit parameter defining a set of numeric operations which includes the * operator to be used in forming the product.
*/
def product[B >: A](num: Numeric[B]): B
So, try it in the Scala interpreter:
scala> val a = List(3, 5, 2)
a: List[Int] = List(3, 5, 2)
scala> a.product
res2: Int = 30
So it seems to work fine. Possible to override the * operator? From the API doc it is clear that the default being used is the IntIsIntegral object:
package scala.math
class Numeric {
object IntIsIntegral extends IntIsIntegral with IntOrdering {
...
}
}
So, the first try is:
scala> import scala.math.Numeric._
import scala.math.Numeric._
scala> val x = new IntIsIntegral {
| override def times(x: Int, y: Int) = x+y;
| }
<console>:9: error: object creation impossible, since method compare in trait Ordering of type (x: Int,y: Int)Int is not defined
Oops, forgot to specify the IntOrdering trait which defines the compare() method. So, do it now:
scala> import scala.math.Ordering._
import scala.math.Ordering._
scala> val x = new IntIsIntegral with IntOrdering {
| override def times(x: Int, y: Int) = x+y;
| }
x: java.lang.Object with math.Numeric.IntIsIntegral with math.Ordering.IntOrdering = $anon$1@1e5d007
We have successfully created a new object to redefine the * operator as just addition. Now, pass it to the product() method:
scala> a
res5: List[Int] = List(3, 5, 2)
scala> a.product(x)
res6: Int = 11
It should be 3+5+2=10 but why the result is 11? Recall that it is doing multiplication, so it is using 1 as the seed for calculation (1+3+5+2). To change the seed from 1 to, say, 0, we can override the one() method:
scala> val x = new IntIsIntegral with IntOrdering {
| override def times(x: Int, y: Int) = x+y;
| override def one = 0;
| }
x: java.lang.Object with math.Numeric.IntIsIntegral with math.Ordering.IntOrdering = $anon$1@11a9f20
scala> a.product(x)
res7: Int = 10
Obviously now it works.
No comments:
Post a Comment