define default named arguments in terms of other arguments in scala - scala

I have a case class that stores three tied parameters. I'd like to define companion object that may build the class from any two parameters, something that looks like the sample below, that is obviously incorrect:
def test(start : Float = end - duration, duration : Float = end - start, end : Float = start + duration) {
require( abs(start + duration - end) < epsilon )
...
}
val t1 = test(start = 0f, duration = 5f)
val t2 = test(end = 4f, duration = 3f)
val t3 = test(start = 3f, end = 5f)
What tricks I may use to get similar usage syntax?

You can use type-classes:
// Represents no argument
object NoArg
// Resolves start, duration, stop
trait DurationRes[A,B,C] {
def resolve(s: A, d: B, e: C): (Float, Float, Float)
}
object DurationRes {
implicit object startEndRes extends DurationRes[Float, NoArg.type, Float] {
def resolve(s: Float, d: NoArg.type, e: Float) = (s, e-s, e)
}
implicit object startDurRes extends DurationRes[Float, Float, NoArg.type] {
def resolve(s: Float, d: Float, e: NoArg.type) = (s, d, s+d)
}
// etc.
}
def test[A,B,C](start: A = NoArg, dur: B = NoArg, end: C = NoArg)
(implicit res: DurationRes[A,B,C]) {
val (s,d,e) = res.resolve(start, dur, end)
// s is start, d duration, e end
}
test(start = 1f, end = 2f)
This way it is even type-safe and you cannot call something like:
test(start = 1f)
or even
test()

After a little thinking I've come with another solution (I don't claim it's better, just would like to know if it's even acceptable approach). The essence is to define a class:
class Klass(val x: Int, val y: Int, val z: Int)
and a companion object:
object Klass {
def apply(x: Int, y: Int)(z: Int = x + y) = {
new Klass(x, y, z)
}
// and so on
}
So you can then do val k = Klass(x = 5, y = 6)() and get val k to refer to Klass(5, 6, 11) instance.
And because of small code amount one can probably define a macros to do the job, but that's a little difficult for me as for now, but is an interesting exercise though.
Update
After some time, I'd like to note to you that there are only three combinations of parameters in your case, so wouldn't it be just easier to provide 3 apply() methods by hand? apply(s, d), apply(s, e), apply(d, e) should suffice your needs. And that will save you some typing, because with other approaches you basically have to code all that cases, too.

Related

Monadic approach to estimating PI in scala

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!

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)
}

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

How do I make a class generic for all Numeric Types?

I am trying to create a Vector class that is generic for all numeric types.
my original attempt was to write a class for all Types like this:
class Vector3f(val x:Float, val y:Float, val z:Float)
since scala supports the specialised annotation I could use this to generate me these classes for all numeric types
class Vector3[A <: What?](val x:A,val y:A, val z:A)
but everything I found as a super type for numbers was AnyVal, but AnyVal does not support + - * /. So what is the right way to do this, but without sacrificing the performance of unboxed number types?
You can't. Not right now. Maybe when, and if, Numeric gets specialized.
Say you get the simplest parameterized class possible:
class Vector3[#specialized T](val x: T, val y: T, val z: T)(implicit num: Numeric[T]) {
def +(other: Vector3[T]) = new Vector3(num.plus(x, other.x), num.plus(y, other.y), num.plus(z, other.z))
}
The method + will compile into something roughly like this:
override <specialized> def +$mcD$sp(other: Vector3): Vector3 = new Vector3$mcD$sp(
scala.Double.unbox(
Vector3$mcD$sp.this.Vector3$$num.plus(
scala.Double.box(Vector3$mcD$sp.this.x()),
scala.Double.box(other.x$mcD$sp()))),
scala.Double.unbox(
Vector3$mcD$sp.this.Vector3$$num.plus(
scala.Double.box(Vector3$mcD$sp.this.y()),
scala.Double.box(other.y$mcD$sp()))),
scala.Double.unbox(
Vector3$mcD$sp.this.Vector3$$num.plus(
scala.Double.box(Vector3$mcD$sp.this.z()),
scala.Double.box(other.z$mcD$sp()))),
Vector3$mcD$sp.this.Vector3$$num);
That's scalac -optimize -Xprint:jvm output. Now there are even subclasses for each specialized type, so that you can initialize a Vector3 without boxing, but as long as Numeric is not specialized, you can't go further.
Well... you can write your own Numeric and specialize that, but, at that point, I'm not sure what you are gaining by making the class parameterized in first place.
The short answer is: you can't get full performance. Or at least I haven't found anything that gives full performance. (And I have tried for a while in exactly this use case; I gave up and wrote a code generator instead, especially since you can't handle different vector sizes generically either.)
I'd be delighted to be shown otherwise, but thus far everything I've tried has had a small (30%) to vast (900%) increase in runtime.
Edit: here's a test showing what I mean.
object Specs {
def ptime[T](f: => T): T = {
val t0 = System.nanoTime
val ans = f
printf("Elapsed: %.3f s\n",(System.nanoTime-t0)*1e-9)
ans
}
def lots[T](n: Int, f: => T): T = if (n>1) { f; lots(n-1,f) } else f
sealed abstract class SpecNum[#specialized(Int,Double) T] {
def plus(a: T, b: T): T
}
implicit object SpecInt extends SpecNum[Int] {
def plus(a: Int, b: Int) = a + b
}
final class Vek[#specialized(Int,Double) T](val x: T, val y: T) {
def +(v: Vek[T])(implicit ev: SpecNum[T]) = new Vek[T](ev.plus(x,v.x), ev.plus(y,v.y))
}
final class Uek[#specialized(Int,Double) T](var x: T, var y: T) {
def +=(u: Uek[T])(implicit ev: SpecNum[T]) = { x = ev.plus(x,u.x); y = ev.plus(y,u.y); this }
}
final class Veq(val x: Int, val y: Int) {
def +(v: Veq) = new Veq(x + v.x, y + v.y)
}
final class Ueq(var x: Int, var y: Int) {
def +=(u: Ueq) = { x += u.x; y += u.y; this }
}
def main(args: Array[String]) {
for (i <- 1 to 6) {
ptime(lots(1000000,{val v = new Vek[Int](3,5); var u = new Vek[Int](0,0); var i=0; while (i<100) { u = (u+v); i += 1 }; u}))
ptime(lots(1000000,{val v = new Veq(3,5); var u = new Veq(0,0); var i=0; while (i<100) { u = (u+v); i += 1 }; u}))
ptime(lots(1000000,{val v = new Uek[Int](3,5); val u = new Uek[Int](0,0); var i=0; while (i<100) { u += v; i += 1 }; u}))
ptime(lots(1000000,{val v = new Ueq(3,5); val u = new Ueq(0,0); var i=0; while (i<100) { u += v; i += 1 }; u}))
}
}
}
and the output:
Elapsed: 0.939 s
Elapsed: 0.535 s
Elapsed: 0.077 s
Elapsed: 0.075 s
Elapsed: 0.947 s
Elapsed: 0.352 s
Elapsed: 0.064 s
Elapsed: 0.063 s
Elapsed: 0.804 s
Elapsed: 0.360 s
Elapsed: 0.064 s
Elapsed: 0.062 s
Elapsed: 0.521 s <- Immutable specialized with custom numeric
Elapsed: 0.364 s <- Immutable primitive type
Elapsed: 0.065 s <- Mutable specialized with custom numeric
Elapsed: 0.065 s <- Mutable primitive type
...
You probably want to use the typeclass pattern as described here: http://dcsobral.blogspot.com/2010/06/implicit-tricks-type-class-pattern.html
Or, you can indirectly use by by using the Numeric trait http://www.scala-lang.org/api/current/scala/math/Numeric.html

Scala: return reference to a function

I'd like to have a Scala functions that returns the reference to another function, is that possible?
You can return a function type (this is defined by A => B). In this case Int to Int:
scala> def f(x:Int): Int => Int = { n:Int => x + n }
f: (x: Int)(Int) => Int
When you call the function you get a new function.
scala> f(2)
res1: (Int) => Int = <function1>
Which can be called as a normal function:
scala> res1(3)
res2: Int = 5
One way (somewhat unique to functional object-orientation) you can use higher order functions is to create loose couplings between objects.
In the example below the class Alarm has a method check4Danger() that checks if a calculated value exceeds the DangerLevel. The Alarm class does not know anything about the objects that call it.
The Car class has a method engineCrashRisk() that returns an anonymous function that calculate the risk of engine crash. Car does not have dependency to Alarm.
case class Alarm(temperature: Double, pressure: Double){
val DangerLevel = 100000.0
def check4Danger( f: (Double, Double) => Double): Boolean = {
val risk = f(temperature, pressure)
if( risk > DangerLevel ){
println("DANGER: "+ risk )
true
}else{
println("Safe: " + risk)
false
}
}
}
case class Car(fuelRate: Double, milage: Int){
def engineCrashRisk() =
(temperature: Double, pressure: Double) =>
temperature * milage + 2*pressure / fuelRate
}
val car = Car(0.29, 123)
val riskFunc = car.engineCrashRisk
val alarm = Alarm(124, 243)
val risk = alarm.check4Danger(riskFunc)
The output of this script is:
Safe: 16927.862068965518
In this example we used anonymous functions with closures to create a dependency free method call between the Alarm and Car objects. Does this example make any sense?