I'm new to Scala, I was reading about scala from the following source: http://docs.scala-lang.org/tutorials/tour/classes
It had the following code:
class Point(var x: Int, var y: Int) {
def move(dx: Int, dy: Int): Unit = {
x = x + dx
y = y + dy
}
override def toString: String =
"(" + x + ", " + y + ")"
}
object Classes {
def main(args: Array[String]) {
val pt = new Point(1, 2)
println(pt)
pt.move(10, 10)
println(pt)
}
}
The output is:
(1, 2)
(11, 12)
I wanted to ask how did the println(pt) function printed the result (1,2)? Should we not call pt.toString() to print the result as shown?
There's an overload of println that accepts a value of type Any (in Predef.scala):
def println(x: Any) = Console.println(x)
Deep inside, it calls x.toString() to get the string to print.
Related
I need to create methods for basic operations for different types so the output of the expression: println(1 + 2*I + I*3 + 2) is 3+5i. I am new to Scala and here is what I have so far:
class IClass() {
var value = 0
def *(number: Int): String = {
//value += number
value + "i"
}
}
object ComplexNumbers {
var TotalValue: Int = 0
var TotalString: String = ""
// ...
def Complex(num1: Int, num2: Int): String ={
num1 + "+" + num2 + "i"
}
implicit class IntMultiply(private val a: Int) extends AnyVal {
def + (b: String)= {
if(b.contains("i")){
TotalValue += a
TotalString.concat(b)
}
}
def * (b: IClass) = {
//b.value += a
a + "i"
}
}
implicit class StringAdd(private val a: String) extends AnyVal {
def + (b: String): String = {
if(b.contains("i")){
}
a + "i"
}
}
def main(args: Array[String]) {
println(Complex(1,2)) // 1+2i
val I = new IClass()
println(1 + 2*I + I*3 + 2) // 3+5i
// val c = (2+3*I + 1 + 4*I) * I
// println(-c) // 7-3i
}
}
I think I am going in a wrong direction with this because by implementing these operation methods on types I get an error in the println: Type Mismach because of the Any return type where I only update fields without returning anything. Any idea how to implement this?
You should think of the complex numbers as a class with certain behaviors, and define it first, rather than focusing on the one concrete side effect you are after at the moment. It seems counter intuitive, but implementing a more abstract/general problem often makes the job easier than trying to narrow it down to just the task at hand.
case class ComplexInt(real: Int, im: Int) {
def + (other: ComplexInt) = ComplexInt(real + other.real, im + other.im)
def * (other: ComplexInt) = ComplexInt(
real * other.real - im * other.im,
real * other.im + im * other.real
)
def unary_- = ComplexInt(-real, -im)
def -(other: ComplexInt) = this + -other
override def toString() = (if(real == 0 && im != 0) "" else real.toString) + (im match {
case 0 => ""
case 1 if real == 0 => "i"
case 1 => " + i"
case n if n < 0 || real == 0 => s"${n}i"
case n => s"+${n}i"
})
}
object ComplexInt {
val I = ComplexInt(0, 1)
implicit def fromInt(n: Int) = ComplexInt(n, 0)
}
Now, you just need to import ComplexInt.I,
and then things like println(1 + 2*I + I*3 + 2) will print 3+5i etc.
You can even do (1 + 2*I)*(2 + 3*I) (evaluates to -4+7i).
When I was playing with the Scala, I couldn't figure out something. Maybe I am doing completely wrong.
I was trying with Rational Example and Complex Example but I couldn't find a way to use operations like R*3/5 and 1/2*R
here is the complex numbers example I am working on
class Complex(val real : Int, val img : Int){
def this(real: Int) = this(real, 0)
def *(that : Complex) = {
val realPart = this.real * that.real + -(this.img * that.img)
val imgPart = this.real * that.img + this.img * that.real
new Complex(realPart, imgPart)
}
override def toString = this.real + "+" + this.img + "i"
}
object Complex {
def apply(real : Int, img : Int) = new Complex(real, img)
def apply(real : Int) = new Complex(real)
}
object ComplexNumbers {
def main(args: Array[String]) {
import ComplexConversions._
println(Complex(1,2)) // 1+2i
println(I*2) //0+2i
println(2*I) //0+2i
}
}
Well I have tried to create an object I
object I{
def apply() = new Complex(0,1)
def *(that : Complex) = {
val realPart = 0 * that.real + -(1 * that.img)
val imgPart = 0 * that.img + 1 * that.real
new Complex(realPart, imgPart)
}
}
but it did work for the I*2. but I have problems for 2*I. How can I reach the result that I want?
When you call "I * 2", scala looks for a method named "*" on the class of I, and finds it.
When you call "2 * I", scala looks for a method named "*" on the class of 2 (which is Int), and cannot find one.
Even though Int is defined externally, you can add this method to it in Scala via the "implicit conversion" mechanism. This is covered briefly in the "implicits" example and in more detail elsewhere, e.g. here
Try adding some code like the following to your "Complex" object:
object Complex {
implicit class IntOps(x: Int) {
def *(y: Complex) = y * x
}
}
You'll also need to declare I as a val, rather than an Object for this to work:
val I = Complex(0, 1)
(or add an implicit method like class Complex { def *(i: I) = ... }, but that's much uglier)
(I assume by Complex Example, you mean this?)
Working code:
class Complex(val real : Int, val img : Int){
def this(real: Int) = this(real, 0)
def *(that : Complex) = {
val realPart = this.real * that.real + -(this.img * that.img)
val imgPart = this.real * that.img + this.img * that.real
new Complex(realPart, imgPart)
}
override def toString = this.real + "+" + this.img + "i"
}
object Complex {
def apply(real : Int, img : Int) = new Complex(real, img)
def apply(real : Int) = new Complex(real)
val I = Complex(0, 1)
implicit def toComplex(x: Int): Complex = new Complex(x)
}
object ComplexNumbers {
def main(args: Array[String]) {
import Complex._
println(Complex(1,2)) // 1+2i
println(I*2) //0+2i
println(2*I) //0+2i
}
}
If you want to be able to use 2*I, you will need to add a new * override for the Int class (since * is really a method of the class Int, meaning 2*I is really 2.*(I)).
You can accomplish this with an implicit class:
scala> case class myInt(i: Int){
| def mult(that: Int): myInt = myInt(that * i)
| }
defined class myInt
scala> implicit class intOverride(i: Int){
| def *(that: myInt): myInt = that.mult(i)
| }
defined class intOverride
scala> val a = myInt(2)
a: myInt = myInt(2)
scala> 2 * a
res1: myInt = myInt(4)
I have the following function which generates a Uniform distributed value between 2 bounds:
def Uniform(x: Bounded[Double], n: Int): Bounded[Double] = {
val y: Double = (x.upper - x.lower) * scala.util.Random.nextDouble() + x.lower
Bounded(y, x.bounds)
}
and Bounded is defined as follows:
trait Bounded[T] {
val underlying: T
val bounds: (T, T)
def lower: T = bounds._1
def upper: T = bounds._2
override def toString = underlying.toString + " <- [" + lower.toString + "," + upper.toString + "]"
}
object Bounded {
def apply[T : Numeric](x: T, _bounds: (T, T)): Bounded[T] = new Bounded[T] {
override val underlying: T = x
override val bounds: (T, T) = _bounds
}
}
However, I want Uniform to work on all Fractional[T] values so I wanted to add a context bound:
def Uniform[T : Fractional](x: Bounded[T], n: Int): Bounded[T] = {
import Numeric.Implicits._
val y: T = (x.upper - x.lower) * scala.util.Random.nextDouble().asInstanceOf[T] + x.lower
Bounded(y, x.bounds)
}
This works swell when doing a Uniform[Double](x: Bounded[Double]), but the other ones are impossible and get a ClassCastException at runtime because they can not be casted. Is there a way to solve this?
I'd suggest defining a new type class that characterizes types that you can get random instances of:
import scala.util.Random
trait GetRandom[A] {
def next(): A
}
object GetRandom {
def instance[A](a: => A): GetRandom[A] = new GetRandom[A] {
def next(): A = a
}
implicit val doubleRandom: GetRandom[Double] = instance(Random.nextDouble())
implicit val floatRandom: GetRandom[Float] = instance(Random.nextFloat())
// Define any other instances here
}
Now you can write Uniform like this:
def Uniform[T: Fractional: GetRandom](x: Bounded[T], n: Int): Bounded[T] = {
import Numeric.Implicits._
val y: T = (x.upper - x.lower) * implicitly[GetRandom[T]].next() + x.lower
Bounded(y, x.bounds)
}
And use it like this:
scala> Uniform[Double](Bounded(2, (0, 4)), 1)
res15: Bounded[Double] = 1.5325899033654382 <- [0.0,4.0]
scala> Uniform[Float](Bounded(2, (0, 4)), 1)
res16: Bounded[Float] = 0.06786823 <- [0.0,4.0]
There are libraries like rng that provide a similar type class for you, but they tend to be focused on purely functional ways to work with random numbers, so if you want something simpler you're probably best off writing your own.
Look at this example:
class Point(x: Double, y: Double){
override def toString = "x: " + x + ", y: " + y
def +(sourcePoint: Point) : Point = {
return new Point(x + sourcePoint.x, y + sourcePoint.y
}
}
As you can see I want to define a + operator method on the Point class. But this won't work
because in that method, x and y can't be accessed on the sourcePoint local variable since they are private, so I changed the example into this:
class Point(_x: Double, _y: Double){
var x = _x
var y = _y
override def toString = "x: " + x + ", y: " + y
def +(sourcePoint: Point) : Point = {
return new Point(x + sourcePoint.x, y + sourcePoint.y)
}
}
That obviously worked, however is there an easier way to define these variables instead of going from _x -> x and _y -> y.
Thanks for help and time! :)
Yes, there is:
class Point(val x: Int, val y: Int)
using val is valid but then the parameter becomes final (constant).
If you want to be able to reassign the value you should use var instead. So
class Point(var x: Int, var y: Int)
How do you provide overloaded constructors in Scala?
It's worth explicitly mentioning that Auxiliary Constructors in Scala must either call the primary constructor (as in landon9720's) answer, or another auxiliary constructor from the same class, as their first action. They cannot simply call the superclass's constructor explicitly or implicitly as they can in Java. This ensures that the primary constructor is the sole point of entry to the class.
class Foo(x: Int, y: Int, z: String) {
// default y parameter to 0
def this(x: Int, z: String) = this(x, 0, z)
// default x & y parameters to 0
// calls previous auxiliary constructor which calls the primary constructor
def this(z: String) = this(0, z);
}
class Foo(x: Int, y: Int) {
def this(x: Int) = this(x, 0) // default y parameter to 0
}
As of Scala 2.8.0 you can also have default values for contructor- and method parameters. Like this
scala> class Foo(x:Int, y:Int = 0, z:Int=0) {
| override def toString() = { "Foo(" + x + ", " + y + ", " + z + ")" }
| }
defined class Foo
scala> new Foo(1, 2, 3)
res0: Foo = Foo(1, 2, 3)
scala> new Foo(4)
res1: Foo = Foo(4, 0, 0)
Parameters with default values must come after the ones with no default values in the parameter list.
While looking at my code, I suddenly realized that I did kind of an overload a constructor. I then remembered that question and came back to give another answer:
In Scala, you can’t overload constructors, but you can do this with functions.
Also, many choose to make the apply function of a companion object a factory for the respective class.
Making this class abstract and overloading the apply function to implement-instantiate this class, you have your overloaded “constructor”:
abstract class Expectation[T] extends BooleanStatement {
val expected: Seq[T]
…
}
object Expectation {
def apply[T](expd: T ): Expectation[T] = new Expectation[T] {val expected = List(expd)}
def apply[T](expd: Seq[T]): Expectation[T] = new Expectation[T] {val expected = expd }
def main(args: Array[String]): Unit = {
val expectTrueness = Expectation(true)
…
}
}
Note that I explicitly define each apply to return Expectation[T], else it would return a duck-typed Expectation[T]{val expected: List[T]}.
Try this
class A(x: Int, y: Int) {
def this(x: Int) = this(x, x)
def this() = this(1)
override def toString() = "x=" + x + " y=" + y
class B(a: Int, b: Int, c: String) {
def this(str: String) = this(x, y, str)
override def toString() =
"x=" + x + " y=" + y + " a=" + a + " b=" + b + " c=" + c
}
}