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
Related
I'm trying to understand how to leverage monads in scala to solve simple problems as way of building up my familiarity. One simple problem is estimating PI using a functional random number generator. I'm including the code below for a simple stream based approach.
I'm looking for help in translating this to a monadic approach. For example, is there an idiomatic way convert this code to using the state (and other monads) in a stack safe way?
trait RNG {
def nextInt: (Int, RNG)
def nextDouble: (Double, RNG)
}
case class Point(x: Double, y: Double) {
val isInCircle = (x * x + y * y) < 1.0
}
object RNG {
def nonNegativeInt(rng: RNG): (Int, RNG) = {
val (ni, rng2) = rng.nextInt
if (ni > 0) (ni, rng2)
else if (ni == Int.MinValue) (0, rng2)
else (ni + Int.MaxValue, rng2)
}
def double(rng: RNG): (Double, RNG) = {
val (ni, rng2) = nonNegativeInt(rng)
(ni.toDouble / Int.MaxValue, rng2)
}
case class Simple(seed: Long) extends RNG {
def nextInt: (Int, RNG) = {
val newSeed = (seed * 0x5DEECE66DL + 0xBL) & 0xFFFFFFFFFFFFL
val nextRNG = Simple(newSeed)
val n = (newSeed >>> 16).toInt
(n, nextRNG)
}
def nextDouble: (Double, RNG) = {
val (n, nextRNG) = nextInt
double(nextRNG)
}
}
}
object PI {
import RNG._
def doubleStream(rng: Simple):Stream[Double] = rng.nextDouble match {
case (d:Double, next:Simple) => d #:: doubleStream(next)
}
def estimate(rng: Simple, iter: Int): Double = {
val doubles = doubleStream(rng).take(iter)
val inside = (doubles zip doubles.drop(3))
.map { case (a, b) => Point(a, b) }
.filter(p => p.isInCircle)
.size * 1.0
(inside / iter) * 4.0
}
}
// > PI.estimate(RNG.Simple(10), 100000)
// res1: Double = 3.14944
I suspect I'm looking for something like replicateM from the Applicative monad in cats but I'm not sure how to line up the types or how to do it in a way that doesn't accumulate intermediate results in memory. Or, is there a way to do it with a for comprehension that can iteratively build up Points?
Id you want to iterate using monad in a stack safe way, then there is a tailRecM method implemented in Monad type class:
// assuming random generated [-1.0,1.0]
def calculatePi[F[_]](iterations: Int)
(random: => F[Double])
(implicit F: Monad[F]): F[Double] = {
case class Iterations(total: Int, inCircle: Int)
def step(data: Iterations): F[Either[Iterations, Double]] = for {
x <- random
y <- random
isInCircle = (x * x + y * y) < 1.0
newTotal = data.total + 1
newInCircle = data.inCircle + (if (isInCircle) 1 else 0)
} yield {
if (newTotal >= iterations) Right(newInCircle.toDouble / newTotal.toDouble * 4.0)
else Left(Iterations(newTotal, newInCircle))
}
// iterates until Right value is returned
F.tailRecM(Iterations(0, 0))(step)
}
calculatePi(10000)(Future { Random.nextDouble }).onComplete(println)
It uses by-name param because you could try to pass there something like Future (even though the Future is not lawful), which are eager, so you would end up with evaluating the same thing time and time again. With by name param at least you have the chance of passing there a recipe for side-effecting random. Of course, if we use Option, List as a monad holding our "random" number, we should also expect funny results.
The correct solution would be using something that ensures that this F[A] is lazily evaluated, and any side effect inside is evaluated each time you need a value from inside. For that you basically have to use some of Effects type classes, like e.g. Sync from Cats Effects.
def calculatePi[F[_]](iterations: Int)
(random: F[Double])
(implicit F: Sync[F]): F[Double] = {
...
}
calculatePi(10000)(Coeval( Random.nextDouble )).value
calculatePi(10000)(Task( Random.nextDouble )).runAsync
Alternatively, if you don't care about purity that much, you could pass side effecting function or object instead of F[Int] for generating random numbers.
// simplified, hardcoded F=Coeval
def calculatePi(iterations: Int)
(random: () => Double): Double = {
case class Iterations(total: Int, inCircle: Int)
def step(data: Iterations) = Coeval {
val x = random()
val y = random()
val isInCircle = (x * x + y * y) < 1.0
val newTotal = data.total + 1
val newInCircle = data.inCircle + (if (isInCircle) 1 else 0)
if (newTotal >= iterations) Right(newInCircle.toDouble / newTotal.toDouble * 4.0)
else Left(Iterations(newTotal, newInCircle))
}
Monad[Coeval].tailRecM(Iterations(0, 0))(step).value
}
Here is another approach that my friend Charles Miller came up with. It's a bit more direct since it uses RNG directly but it follows the same approach provided by #Mateusz Kubuszok above that leverages Monad.
The key difference is that it leverages the State monad so we can thread the RNG state through the computation and generate the random numbers using the "pure" random number generator.
import cats._
import cats.data._
import cats.implicits._
object PICharles {
type RNG[A] = State[Long, A]
object RNG {
def nextLong: RNG[Long] =
State.modify[Long](
seed ⇒ (seed * 0x5DEECE66DL + 0xBL) & 0xFFFFFFFFFFFFL
) >> State.get
def nextInt: RNG[Int] = nextLong.map(l ⇒ (l >>> 16).toInt)
def nextNatural: RNG[Int] = nextInt.map { i ⇒
if (i > 0) i
else if (i == Int.MinValue) 0
else i + Int.MaxValue
}
def nextDouble: RNG[Double] = nextNatural.map(_.toDouble / Int.MaxValue)
def runRng[A](seed: Long)(rng: RNG[A]): A = rng.runA(seed).value
def unsafeRunRng[A]: RNG[A] ⇒ A = runRng(System.currentTimeMillis)
}
object PI {
case class Step(count: Int, inCircle: Int)
def calculatePi(iterations: Int): RNG[Double] = {
def step(s: Step): RNG[Either[Step, Double]] =
for {
x ← RNG.nextDouble
y ← RNG.nextDouble
isInCircle = (x * x + y * y) < 1.0
newInCircle = s.inCircle + (if (isInCircle) 1 else 0)
} yield {
if (s.count >= iterations)
Right(s.inCircle.toDouble / s.count.toDouble * 4.0)
else
Left(Step(s.count + 1, newInCircle))
}
Monad[RNG].tailRecM(Step(0, 0))(step(_))
}
def unsafeCalculatePi(iterations: Int) =
RNG.unsafeRunRng(calculatePi(iterations))
}
}
Thanks Charles & Mateusz for your help!
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)
}
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)
So I have a Vec2 class:
class Vec2(val x: Double, val y: Double)
{
def +(other: Vec2): Vec2 = Vec2(x + other.x, y + other.y)
def -(other: Vec2): Vec2 = Vec2(x - other.x, y - other.y)
def *(factor: Double): Vec2 = Vec2(x * factor, y * factor)
def /(divisor: Double): Vec2 = Vec2(x / divisor, y / divisor)
//Other methods omitted but you get the idea
}
I use this class a lot and I use it a lot in collections, so I would like short hand methods for .map(_ + other) .map(_ * factor) etc. I also want to add methods for addMultAll(second: Vec2, factor: Double) and multAddAll(factor: Double, second: Vec2) that I think would be clearer and safer as explicit methods.
So I chose the traversable class for my implicit. Is this the best / most general class that I can use? I have cribbed and modifed the map method from the scala source code. Is the code below correct? Will it work without problems?
object Vec2
{
import collection.mutable.{ Builder }
import scala.collection._
implicit class ImpVec2Class[+Repr](travLike: TraversableLike[Vec2, Repr])
{
def +++ [That](offset: Vec2)(implicit bf: generic.CanBuildFrom[Repr, Vec2, That]): That =
{
def builder =
{ // extracted to keep method size under 35 bytes, so that it can be JIT-inlined
val b = bf(travLike.repr)
b.sizeHint(travLike)
b
}
val b = builder
for (x <- travLike) b += x + offset
b.result
}
}
}
Do I need to do this for the map methods on Double if I want shortened methods, or does Scalaz / CATS already include them?
OK I'm going to post this as answer as its a slight improvement. I've removed the [That] type parameter on the method. I've also added an implict for Array[Vec2] as Array doesn't inherit from the Scala collection traits.
object Vec2
{
import collection.mutable.{ Builder }
import scala.collection._
implicit class ImpVec2Traversible[Repr](travLike: TraversableLike[Vec2, Repr])
{
def +++ (offset: Vec2)(implicit bf: generic.CanBuildFrom[Repr, Vec2, Repr]): Repr =
{
def builder =
{ // extracted to keep method size under 35 bytes, so that it can be JIT-inlined
val b = bf(travLike.repr)
b.sizeHint(travLike)
b
}
val b = builder
for (x <- travLike) b += x + offset
b.result
}
}
implicit class ImpVec2Array(arr: Array[Vec2])
{
def +++ (offset: Vec2): Array[Vec2] = arr.map(_ + offset)
}
}
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.