Overloaded method value with alternatives - scala

I have the following:
def calc(dir: File): Option[Group] = {
calcModel(dir) match {
case Some(model: Model) => calcUI(model, centerpane.getWidth, centerpane.getHeight, 5, MAX_LEVEL)
case None => None
}
}
def calcUI(model: Model, availableWidth: Double, availableHeight: Double, maxLevel: Int): Option[Group] = {
}
def calcUI(model: Model, posX: Double, posY: Double, availableWidth: Double, availableHeight: Double, horizontally: Boolean, startLevel: Int, maxLevel: Int): Option[Group] = {
}
protected def calcUI(node: Node, posX: Double, posY: Double, availableWidth: Double, availableHeight: Double, horizontally: Boolean, level: Int, maxLevel: Int): Group = {
}
def calcModel(dir: File): Option[Model] = {
}
(Remark: Model does NOT derive from Node)
and get the following compiler error message:
Error:(88, 27) overloaded method value calcUI with alternatives:
(node: org.rob.spaceview.modell.Node,posX: Double,posY: Double,availableWidth: Double,availableHeight: Double,horizontally: Boolean,level: Int,maxLevel: Int)javafx.scene.Group <and>
(model: org.rob.spaceview.modell.Model,posX: Double,posY: Double,availableWidth: Double,availableHeight: Double,horizontally: Boolean,startLevel: Int,maxLevel: Int)Option[javafx.scene.Group] <and>
(model: org.rob.spaceview.modell.Model,availableWidth: Double,availableHeight: Double,maxLevel: Int)Option[javafx.scene.Group]
cannot be applied to (org.rob.spaceview.modell.Model, Double, Double, Int, Int)
case Some(model) => calcUI(model, centerpane.getWidth, centerpane.getHeight, 5, MAX_LEVEL)
^
I do not get it. All calcUI functions are different by parameters.
I know this error and most of the time I get it and fix it. But here, no clue.
Hopefully somebody enlights me. Thanks.

Actually, the given parameters in the call
case Some(model) => calcUI(model, centerpane.getWidth, centerpane.getHeight, 5, MAX_LEVEL)
don't correspond to any defined calcUI method. For example for the following definition
def calcUI(model: Model, availableWidth: Double, availableHeight: Double, maxLevel: Int): Option[Group]
you have one more argument than needed.

Related

How to find min value in triple RDD

I want to find minimum value over RDD triples. This is how I approach this task (saving to file is done for validation).
evalsRDD.coalesce(1)
.map(e => "%.3f\t%d\t%.3f".format(e._1, e._2, e._3))
.saveAsTextFile("data/streaming/test")
val minRMSE = evalsRDD.min()(new Ordering[(Any, Any, Double)]() {
override def compare(x: (Any, Any, Double), y: (Any, Any, Double)): Double =
Ordering[Double].compare(x._3, y._3) })
It says that method compare has incompatible type. How to solve this issue?
Your compare method must return an Int, not a Double, to override the method defined in Ordering.
If you change it do to so, it works:
val minRMSE = evalsRDD.min()(new Ordering[(Any, Any, Double)]() {
override def compare(x: (Any, Any, Double), y: (Any, Any, Double)): Int =
Ordering[Double].compare(x._3, y._3)
})

Passing function to overloaded method in Scala

I've hit an interesting issue with passing function references to overloaded methods in Scala (Using 2.11.7)
The following code works as expected
def myFunc(a: Int, b: String): Double = {
a.toDouble + b.toDouble
}
def anotherFunc(value: String, func: (Int, String) => Double) = {
func(111, value)
}
anotherFunc("123123", myFunc)
But the following code doesn't compile
def myFunc(a: Int, b: String): Double = {
a.toDouble + b.toDouble
}
def anotherFunc(value: String, func: (Int, String) => Double) = {
func(111, value)
}
def anotherFunc(value: Int, func: (Int, String) => Double) = {
func(value, "123123")
}
anotherFunc("123123", myFunc)
Compiler shouts the following
scala> anotherFunc("123123", myFunc)
<console>:13: error: type mismatch;
found : String("123123")
required: Int
anotherFunc("123123", myFunc)
Are you using Scala REPL? One of it's design decisions is that if you have two variables/functions with the same name defined then "last defined wins". In your case it is a function with Int parameter.
You can print all defined symbols in REPL using:
$intp.definedTerms.foreach(println)
Here someone had similar question: Why its possible to declare variable with same name in the REPL?
I don't know the reason but seems you have to write
anotherFunc("123123", myFunc _)
to make it work.

How to compute a value to pass into a primary constructor from an auxiliary constructor?

I want to define an auxiliary constructor which should compute some value and use it in multiple parameters passed to a primary constructor. A natural way to express this would be to define local vals before calling the primary constructor, but this is not allowed by the language:
object Computed {
def veryComplexComputation(x: Double) = math.sqrt(x) // imagine there is some much more complex computation here
}
class Computed(x: Double, y: Double, z: Double) {
def this(x: Double, y: Double) = {
val derivedFromX = Computed.veryComplexComputation(x)
val derivedFromY = derivedFromX * Computed.veryComplexComputation(y)
this(x, derivedFromX, derivedFromY)
}
}
An alternative is to repeat the computation, but with very complex computations this can be a problem (and it also leads to a code repetition):
class Computed(x: Double, y: Double, z: Double) {
def this(x: Double, y: Double) = {
this(
x,
Computed.veryComplexComputation(x),
Computed.veryComplexComputation(x) * Computed.veryComplexComputation(y)
)
}
}
The best trick I know is to use a third, private constructor taking a tuple of the parameters for the primary constructor, together with a helper function in the companion object:
object Computed {
def veryComplexComputation(x: Double) = math.sqrt(x) // imagine there is some much more complex computation here
private def computeArgs(x: Double, y: Double): (Double, Double, Double) = {
val derivedFromX = veryComplexComputation(x)
val derivedFromY = derivedFromX * veryComplexComputation(y)
(x, derivedFromX, derivedFromY)
}
}
class Computed(x: Double, y: Double, z: Double) {
private def this(xyz: (Double, Double, Double)) =
this(xyz._1, xyz._2, xyz._3)
def this(x: Double, y: Double) =
this(Computed.computeArgs(x, y))
}
I think the best way is to add a suitable factory method to the companion object:
object Computed {
def veryComplexComputation(x: Double) = math.sqrt(x) // can be private, if you wish
def apply(x: Double, y: Double): Computed = {
val derivedFromX = veryComplexComputation(x)
val derivedFromY = derivedFromX * veryComplexComputation(y)
new Computed(x, derivedFromX, derivedFromY)
}
}
then you can instantiate your Computed type the same way as for case classes, foregoing the use of "new":
scala> val comp = Computed(4.0, 9.0)
comp: Computed = Computed#4de4e24f
(You might also want to consider making Computed a case class anyway - particularly if is entirely, or even mostly, used as a container for data)
One can (ab)use multiple parameter lists with default values, like this:
class Computed(x: Double, y: Double, z: Double) {
def this(x: Double, y: Double)(
derivedFromX: Double = Computed.veryComplexComputation(x)
)(
derivedFromY: Double = derivedFromX * Computed.veryComplexComputation(y)
) = {
this(x, derivedFromX, derivedFromY)
}
}
This exploits the fact each parameter list can access parameters from previous lists. Just do not forget to provide the empty parameter lists when calling the constructor:
new Computed(1, 2)()()
One can chain several auxiliary constructors, each of them performing one computation, using marker traits to distinguish between constructors to avoid overloading ambiguity.
object Computed {
def veryComplexComputation(x: Double) = math.sqrt(x) // imagine there is some much more complex computation here
private trait DerivedFromX
private object DerivedFromX extends DerivedFromX
}
class Computed(x: Double, y: Double, z: Double) {
private def this(name: Computed.DerivedFromX, x: Double, derivedFromX: Double, y: Double) = {
this(x, derivedFromX, derivedFromX * Computed.veryComplexComputation(y))
}
def this(x: Double, y: Double) = this(Computed.DerivedFromX, x, Computed.veryComplexComputation(x), y)
}

For debugging I would like println in functions with explicit return types

I keep getting error: type mismatch: found Uint required Double
When I put a println function in the sqrt method. While I appreciate its part of Scala preventing side effects, how do print values in functions so I can make sense of my programs? Is there a "clean" way to print values in a function that needs an explicit return type (like the recursive function sqrt)?
Code here:
object Newton {
def threshold(guess: Double, x: Double) : Boolean =
if (Math.abs(guess * guess -x) < (0.01/100 * x)) true else false
def improve(guess: Double, x: Double) : Double =
(guess + x/guess) / 2.0
def sqrt(guess: Double, x: Double,
threshold: (Double, Double) => Boolean,
improve: (Double, Double) => Double ): Double =
println("current guess:", guess)
if(threshold(guess,x))
return guess
else
return sqrt(improve(guess, x), x, threshold, improve)
def main(args: Array[String]): Unit = {
println("Sqrt of Two:", sqrt(1,1.0e-20,threshold, improve))
}
}
You are missing curly braces.
def sqrt(guess: Double, x: Double,
threshold: (Double, Double) => Boolean,
improve: (Double, Double) => Double ): Double = { // Add curly braces
println("current guess:", guess)
if(threshold(guess,x))
return guess
else
return sqrt(improve(guess, x), x, threshold, improve)
} // Add curly braces

How do I write a scala extractor for a case class with default parameters?

I have the following case class with a default parameter and I'm wondering how I can write an unapply method so that I can just extract the first two parameters.
I hope the code below is clear.
case class Point(x: Double, y: Double, _key: Option[String] = None) {
def key: String = _key.getOrElse("")
}
object Point {
def unapply(p: Point) = (p.x, p.y)
}
// pSeq is Seq[Point]
pSeq.map { case Point(x,y) => x + y } // This causes a compiler error:
// wrong number of arguments for <none>:
// (x: Double, y: Double, _key: Option[String])
I'm not sure if this is what you are looking for, but it would give you the API that you describe.
sealed abstract class Point(x: Double, y: Double)
case class PointKey(x: Double, y: Double, _key: String) extends Point(x,y)
case class PointNoKey(x: Double, y: Double) extends Point(x,y)
object Point {
def apply(x: Double, y: Double) = PointNoKey(x,y)
def apply(x: Double, y: Double, _key: String) = PointKey(x,y,_key)
def unapply(p: Point): Option[(Double,Double)] = p match {
case PointNoKey(x,y) => Some(x,y)
case PointKey(x,y,_) => Some(x,y)
}
}
I think that just using a wildcard in the case class is preferred if that will work for you.
pSeq.map { case Point(x,y,_) => x + y }