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)
Related
I have two implicit declarations that "redefine" x as an operator:
import scala.io.StdIn._
import util._
import scala.language.postfixOps
case class Rectangle(width: Int, height: Int)
case class Circle(ratio: Integer)
case class Cylinder[T](ratio: T, height: T)
object implicitsExample1 {
implicit class RectangleMaker(width: Int) {
def x(height: Int) = Rectangle(width, height)
}
implicit class CircleMaker(ratio: Int) {
def c = Circle(ratio)
}
implicit class CylinderMaker[T](ratio: T) {
def x(height: T) = Cylinder(ratio, height)
}
def main(args: Array[String]) {
val myRectangle = 3 x 4
val myCircle = 3 c
val myCylinder = 4 x 5
println("myRectangle = " + myRectangle)
println("myCircle = " + myCircle)
println("myCylinder = " + myCylinder)
}
}
Here my output gives:
myRectangle = Rectangle(3,4)
myCircle = Circle(3)
myCylinder = Rectangle(4,5)
What I need to do to have something like:
myCylinder = Cylinder[Int](4,5)
I understand that the chosen implicit conversion is the first one declared but is there a way to specify the use of the Cylinder one?
Try combining RectangleMaker and CylinderMaker into a single ShapeMaker implicit class like so
implicit class ShapeMaker[T](width: T) {
def x(height: T)(implicit ev: T =:= Int) = Rectangle(width, height)
def x(height: T) = Cylinder[T](width, height)
}
and provide type ascriptions to value definitions like so
val myRectangle: Rectangle = 3 x 4
val myCircle = 3 c
val myCylinder: Cylinder[Int] = 4 x 5
which outputs
myRectangle = Rectangle(3,4)
myCircle = Circle(3)
myCylinder = Cylinder(4,5)
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).
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.
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.
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