companion object as factory in scala - scala

I am just starting out with Scala, and working on some tutorials. I came across companion object, and using them as factory. I tried several things out. However I am not getting the following to work properly. Cant get my head around it..
import math._
abstract class Point{
// ...
}
object Point{
private class PointInt(val x:Int,val y:Int) extends Point{
def +(that:PointInt) = new PointInt(this.x + that.x, this.y + that.y)
def distance(that:PointInt) =
sqrt(pow((this.x - that.x), 2) + pow((this.y - that.y), 2))
}
private class PointDouble(val x:Double,val y:Double) extends Point{
def +(that:PointDouble) = new PointDouble(this.x + that.x, this.y + that.y)
def distance(that:PointDouble) =
sqrt(pow((this.x - that.x), 2) + pow((this.y - that.y), 2))
}
def apply(x:Int,y:Int):Point = new PointInt(x,y)
def apply(x:Double,y:Double):Point = new PointDouble(x,y)
}
val a = Point(1,2)
val b = Point(3,4)
val c = a+b // does not work...
Just trying to add up two integer Points, like I defined it in the methods... Does anyone know what I am doing wrong??
EDIT: I was was trying to wrap the following (working) class in an Factory.
class Point(val x:Int,val y:Int){
def +(that:Point) = new Point(this.x + that.x, this.y + that.y)
def distance(that:Point) = sqrt(pow((this.x - that.x),2) + pow((this.y - that.y),2))
}
val a = new Point(1,2) //> a : week1.OU2.Point = week1.OU2$Point#73e48fa7
val b = new Point(3,4) //> b : week1.OU2.Point = week1.OU2$Point#677bb8fe
val c = a+b //> c : week1.OU2.Point = week1.OU2$Point#6bae60c5
c.x //> res0: Int = 4
c.y //> res1: Int = 6

I am not quite sure which constraints are actually imposed on you, for example, which classes should/must be private, but using F-bounded polymorphism might be a stepping stone to your desired solution.
/* Simplified interface (adding sqrt is straight-forward) */
abstract class Point[P <: Point[P]] {
def +(that: P): P
}
/* Two implementations */
class PointInt(val x:Int,val y:Int) extends Point[PointInt] {
def +(that:PointInt) = new PointInt(this.x + that.x, this.y + that.y)
}
class PointDouble(val x:Double,val y:Double) extends Point[PointDouble] {
def +(that:PointDouble) = new PointDouble(this.x + that.x, this.y + that.y)
}
/* Companion object */
object Point {
def apply(x:Int,y:Int) = new PointInt(x,y)
def apply(x:Double,y:Double) = new PointDouble(x,y)
}
/* Use cases */
val a = Point(1,2)
val b = Point(3,4)
val c = a+b // ok
val d = Point(1.0, 2.5)
val e = c+d // error: type mismatch
Notice, however, that this won't help you in case you want to hide your implementations, i.e., make them private and declare public interfaces using the generic Point only - as others pointed out already.

Related

A bady-written Scala code. How would look a well-written one? (playing with programming paradigms and techniques)

I am a Scala newbie. The following code is my extension of the first lesson from "Functional Programming Principles in Scala" course by professor Martin Odersky from the first lesson about Rationals "Functions and Data".
I have added opti method that divides nominator and denominator by their greatest common divisor (gcd) for example makes 2/4 becomes 1/2. But just for fun I have decided to add possibility of adding automatic optimization after each call of add and Sub (forget about performance for this time). So I can write method makeOptiAuto(Boolean): Unit but this would require if statement in each and/sub method. So I decided to make a class called OptimalizedRational and that it will call opti at the end of each
and/sub call.
The problem is, that I have make it as extension of my Rational class. Maybe it should be it's member (Rational.OptimaliyedRational)?
Secondly, I must call Rational constructor. Is that necessary in this case? In fact, I am overriding them, so Rational constructor is useless. I can call gcd like extends Rational(gcd(x, y) / x, gcd(x, y) / y) but it's the same value. So I have use val. Is it possible to call Rational constructor using gcd only once? What is the best way of doing that type of work?
Another problem is in add/sub methods. If I want to call method by using super, then I have Rational object returned, so if I want OptimalizedRational back, I need to use optiAuto again... Maybe I should use asInstanceOf[Rational] to cast it, but first, it doesn't work (an error is thrown), and second, it's slow (Java casts dynamically, if I am not wrong).
So, who would look the well-written Scala code that does what I was trying to do? Can someone sent the corrected version with some explanations?
The code:
object Learning {
// IMMPLEMENTATION OF `Rational` CLASS:
class Rational(x: Int, y: Int) {
def nom = x
def denom = y
def add(that: Rational): Rational =
new Rational((nom*that.denom + that.nom*denom), (denom*that.denom))
def neg: Rational =
new Rational(-nom, denom)
def sub(that: Rational): Rational =
add(that.neg)
// used by opti() and for OptimalizedRational
protected def gcd(a: Int, b: Int): Int =
if (b == 0) a
else gcd(b, a % b)
def opti(): Rational = {
val d = gcd(nom, denom)
new Rational(nom / d, denom / d)
}
// shorthand methods:
def add(a: Int, b: Int): Rational = add(new Rational(a, b))
def sub(a: Int, b:Int): Rational = sub(new Rational(a, b))
// OptimalizedRational immplementation (between classes):
def optiAuto() = new OptimalizedRational(nom, denom)
def isOpti = false
// others:
override def toString = { opti(); nom + "/" + denom }
}
class OptimalizedRational(x: Int, y: Int) extends Rational(x, y) {
// constructor:
val d = gcd(x, y)
override def nom = x / d
override def denom = y / d
// basic behaviour via method overriding:
override def add(a: Int, b: Int) = super.add(a, b).opti().optiAuto()
override def sub(a: Int, b: Int) = super.sub(a, b).opti().optiAuto()
// OptimalizedRational immplementation (between classes):
def optiNoAuto() = new Rational(nom, denom)
override def isOpti = true
}
// TESTING:
new Rational(2, 3).optiAuto().add(1, 2).sub(3, 4)
new Rational(10, 24).opti().toString()
new OptimalizedRational(10, 24).toString()
new Rational(10, 24).toString()
}
Each Rational object is immutable. Why not simply add logic simply that optimizes the Rational on instantiation?
class Rational(x: Int, y: Int) {
protected def gcd(a: Int, b: Int): Int = {
if (b == 0) a
else gcd(b, a % b)
}
//Calculate once
val d = gcd(x, y)
val xOverD = x / d
val yOverD = y / d
def nom = xOverD
def denom = yOverD
def add(that: Rational): Rational =
new Rational((nom*that.denom + that.nom*denom), (denom*that.denom))
def neg: Rational =
new Rational(-nom, denom)
def sub(that: Rational): Rational =
add(that.neg)
override def toString = { nom + "/" + denom }
}
Alternatively, if you really wanted to split them up, it would suffice to simply override the nom and denom methods you would still need to override the methods to have a return type of OptimalizedRational, to do this a little more nicely, we can use an implicit conversion to convert all our Rationals to OptimalizedRationals
class OptimalizedRational(x: Int, y: Int) extends Rational(x, y) {
//Calculate once
private val d = gcd(x, y)
private val xOverD = x / d
private val yOverD = y / d
override def nom = xOverD
override def denom = yOverD
private implicit def convert(rational: Rational): OptimalizedRational =
new OptimalizedRational(rational.nom, rational.denom)
override def add(that: Rational): OptimalizedRational =
super.add(that)
override def neg: OptimalizedRational =
super.neg
override def sub(that: Rational): OptimalizedRational =
super.add(super.neg)
}

Creating Singleton Object from a class in Scala

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)

Using a double value in a Fractional[T] method

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.

Commutative operator definition in Scala

Let's say I define some operators for my class like this:
class A {
def +(f: Float) = /* ... */
}
val a: A = new A
This allows me to do a + 1f, easy enough. What if I want to enable the lib's user to be able to write 1f + a, too? How can I implement that?
In Scala 2.9 you can import this implicit conversion:
implicit def floatPlusAExtender (x: Float) =
new {
def + (a: A) = a + x
}
and use it as you wanted. Since Scala 2.10 you better do this conversion like so:
implicit class FloatPlusAExtender (x: Float) {
def + (a: A) = a + x
}
or even better like so:
implicit class FloatPlusAExtender (val x: Float) extends AnyVal {
def + (a: A) = a + x
}
The last way is called Value Class and in difference to preceding two it provides this functionality with zero overhead. (Thanks, axel22) This is also the new stuff that comes with 2.10
Or you can just modify A like so:
class A {
def + (x: Float) = /* ... */
def +: (x: Float) = this + x
}
and use it like so:
1f +: a
The last approach is preferable.
One approach is the pimp-my-library-pattern:
class FloatWithPlusA(f: Float) {
def +(a: A) = a + f
}
implicit def floatPlusA(f: Float): FloatWithPlusA =
new FloatWithPlusA(f)
val a: A = new A
a + 1.0f /* a.+(1.0f) */
1.0f + a /* floatPlusA(1.0f).+(a) */
Another approach is adding a right-associative method, but with the obvious disadvantage that the syntax of the two operators varies:
class A {
val f: Float = 1.0f
def +(f: Float) = this.f + f
def +:(f: Float) = this.f + f
}
val a: A = new A
a + 1.0f
1.0f +: a

New Instances of Decorated Instances

I have a set of decorator-traits (for simplicity here only trait T) mixing in classes (here subclasses of A).
trait T { def i: Int }
abstract class A
type AT = A with T
class B extends A
// class C extends A
// class D extends A
// ...
Now I have an instance a of e.g. class B which I handle as an instance of type AT (together with other A-subclass-AT-instances in a Seq[AT]).
val a: AT = new B with T { val i = 8 }
How can I generically decorate like this:
def toAT(a: A, i: Int): AT = {
// how to ???
}
An obvious solution I thought about is:
trait T { def i: Int }
abstract class A {
def asAT(i: Int): AT
}
class B extends A {
def asAT(ii: Int): AT = new B with T { val i = ii }
}
type AT = A with T
def toAT(a: A, i: Int): AT = a.asAT(i)
But I donĀ“t want to pollute my classes B, C, ..., Z with a new method and there are other decorations, so for every decoration-combo I need a new method for all subclasses!
Is there a more generic way?
EDIT:
An example why I need the toAT method, but still with the obvious solution approach from above in terms of a redecorated method:
trait T { def b: Boolean}
type AT = A with T
abstract class A(val i: Int) {
def changedBy(x: Int): A
def redecorated(oldAT: AT): AT
}
class B(x: Int) extends A(x) {
def changedBy(x: Int): A = new B(i * x)
def redecorated(oldAT: AT): AT = new B(i) with T { val b = oldAT.b }
}
class C(x: Int) extends A(x) {
def changedBy(x: Int): A = new C(i * x * x)
def redecorated(oldAT: AT): AT = new C(i) with T { val b = oldAT.b }
}
val b = new B(1) with T { val b = true }
val c = new C(1) with T { val b = false }
val x = 8
val res: Seq[AT] = Seq(b,c) map { at => at.changedBy(x).redecorated(at) }
Basically, you can't do it.
One alternative is to use the auto proxy plugin, by Kevin Wright. See also here and here for more information about it.