Scala: type mismatch - scala

I spend awful amount of time to figure it out following:
rmseList is a List of doubles
val rmseList = List(Double)
var tempRMSE : Double = 0.0;
for(rmse <- rmseList) {
val idx = rmseList.indexOf(rmse) + 1
tempRMSE = rmse
}
I get following error, when I am trying to iterate list and assign current value to temp variable.
[error] found : Double.type
[error] required: Double
[error] tempRMSE = rmse

You've probably put the companion object for Double into a list instead of actually putting doubles there. Here's an example:
scala> val xs = List(Double)
xs: List[Double.type] = List(object scala.Double)
scala> var d: Double = 0
d: Double = 0.0
scala> for (x <- xs) { d = x }
<console>:10: error: type mismatch;
found : Double.type
required: Double
for (x <- xs) { d = x }
As to how you managed to put the companion object in instead of Double values, I don't know, because you didn't show us how you built the list. Maybe somehow using parens (Double) instead of brackets [Double] to specify the type?

Related

Unable to create a variable of an Enumeration

I have created an Enumeration as follows:
scala> object J extends Enumeration {
| type J = Value
| val Fail, Success = Value
| }
defined object J
Question 1 - I tried to create a variable of its type but got the following error. Why?
scala> val j:J
<console>:11: error: not found: type J
val j:J
^
<console>:11: error: only classes can have declared but undefined members
val j:J
^
Question 2 - I could create a variable as follows. I suppose the Fail's value is actually 0. How could I print 0?
scala> val j = J.Fail
j: J.Value = Fail
scala> println(j)
Fail
You are using the wrong syntax to assign a type variable, you should do:
val j = J
j: J.type = J
Regarding the value, Fail and Sucess has no value apart from its own name, if you want to assign a value to them you should use this syntax:
object J extends Enumeration {
type J = Value
val Fail = Value(0)
val Success = Value(1)
}
Then you can access to it ussing its id property
scala> j.id
res: Int = 0
scala> j
res: J.Value = Fail

What is the "real" difference between val b and var b?

What is the "real" difference between the following ?
val b = ( x:Double) => x * 3
var b = ( x:Double) => x * 3
Technically speaking, once a value is assigned to val , it should not be changed. However, as part of the first statement, the value of b could be changed to different values by passing different values of x.
scala> val b = ( x:Double) => x * 3
b: Double => Double = $$Lambda$1109/411756754#7a522157
scala> b(3)
res1: Double = 9.0
scala> b(4)
res2: Double = 12.0
What is actually happening here? Is it not that value of b is changing here?
b is a function that takes a Double and returns a one.
The function itself can't be changed, not the value it returns (functions are first class values).
If you try to do:
b = (x : Double) => x * 6
you'll get:
error: reassignment to val
But it's possible to change the var one:
scala> b = (x : Double) => x * 7
b: Double => Double = $$Lambda$1308/1272194712#9e46050
But note that when you change the var one, you should keep its type: A function that takes a Double and returns a Double, the same if you were to change any other type like Integer or Boolean.
In the example posted by you b is a function. You are passing different values to the function subsequently. Value of b is not changed by that.
Syntax is as follows:

What is the most concise way to increment a variable of type Short in Scala?

I've been working a bit lately on implementing a binary network protocol in Scala. Many of the fields in the packets map naturally to Scala Shorts. I would like to concisely increment a Short variable (not a value). Ideally, I would like something like s += 1 (which works for Ints).
scala> var s = 0:Short
s: Short = 0
scala> s += 1
<console>:9: error: type mismatch;
found : Int
required: Short
s += 1
^
scala> s = s + 1
<console>:8: error: type mismatch;
found : Int
required: Short
s = s + 1
^
scala> s = (s + 1).toShort
s: Short = 1
scala> s = (s + 1.toShort)
<console>:8: error: type mismatch;
found : Int
required: Short
s = (s + 1.toShort)
^
scala> s = (s + 1.toShort).toShort
s: Short = 2
The += operator is not defined on Short, so there appears to be an implicit converting s to an Int preceding the addition. Furthermore Short's + operator returns an Int.
Here's how it works for Ints:
scala> var i = 0
i: Int = 0
scala> i += 1
scala> i
res2: Int = 1
For now I'll go with s = (s + 1).toShort
Any ideas?
You could define an implicit method that will convert the Int to a Short:
scala> var s: Short = 0
s: Short = 0
scala> implicit def toShort(x: Int): Short = x.toShort
toShort: (x: Int)Short
scala> s = s + 1
s: Short = 1
The compiler will use it to make the types match. Note though that implicits also have a shortfall, somewhere you could have a conversion happening without even knowing why, just because the method was imported in the scope, code readability suffers too.

Scala methods ending in _=

I seem to remember Scala treating methods ending in _= specially, so something like this:
object X { var x: Int = 0; def y_=(n : Int) { x = n }}
X.y = 1
should call X.y_=(1). However, in 2.8.0 RC1, I get an error message:
<console>:6: error: value y is not a member of object X
X.y = 1
^
Interestingly, just trying to call the method without parentheses fails as well:
scala> X.y_= 1
<console>:1: error: ';' expected but integer literal found.
X.y_= 1
^
Am I misremembering something which does actually exist or did I just invent it out of whole cloth?
This is one of those corner cases in Scala. You cannot have a setter without a getter and vice versa.
The following works fine:
scala> object X {
| var x: Int = 0
| def y = x
| def y_=(n: Int) { x = n }
| }
defined module X
scala> X.y = 45
scala> X.y
res0: Int = 45
scala> object X { var x: Int = 0; def y_=(n : Int) { x = n }}
defined module X
scala>
scala> X y_= 1
scala> X.x
res1: Int = 1
scala> object X { var x: Int = _; def y = x ; def y_=(n: Int) { x = n } }
defined module X
scala> X.y = 1
scala> X.y
res2: Int = 1
scala>

Number formatting in Scala?

I have a dynamically changing input reading from a file. The numbers are either Int or Double. Why does Scala print .0 after every Double number? Is there a way for Scala to print it the same way it reads it?
Example:
var x:Double = 1
println (x) // This prints '1.0', I want it to print '1'
x = 1.0 // This prints '1.0', which is good
I can't use Int because some of the input I get are Doubles. I can't use String or AnyVal because I perform some math operations.
Thank you,
scala> "%1.0f" format 1.0
res3: String = 1
If your input is either Int or Double, you can do it like this:
def fmt(v: Any): String = v match {
case d : Double => "%1.0f" format d
case i : Int => i.toString
case _ => throw new IllegalArgumentException
}
Usage:
scala> fmt(1.0)
res6: String = 1
scala> fmt(1)
res7: String = 1
scala> fmt(1.0f)
java.lang.IllegalArgumentException
at .fmt(<console>:7)
at .<init>(<console>:6)
at .<clinit>(<console>)
at RequestResult$.<init>(<console>:4)
at RequestResult$.<clinit>(<console>)
at RequestResult$result(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.Dele...
Otherwise, you might use BigDecimals. They are slow, but they do come with the scale, so "1", "1.0" and "1.00" are all different:
scala> var x = BigDecimal("1.0")
x: BigDecimal = 1.0
scala> x = 1
x: BigDecimal = 1
scala> x = 1.0
x: BigDecimal = 1.0
scala> x = 1.000
x: BigDecimal = 1.0
scala> x = "1.000"
x: BigDecimal = 1.000
var x:Double = 1
var y:Double = 1.0
print(x) // => 1.0
print(y) // => 1.0
If i understand you question you want scala to print x and y differently? The problem is that x and y are both a variable of the type Double and look the same.
Why do you explicitly define the type of the vars?
var x = 1
var y= 1.0
print(x) // => 1
print(y) // => 1.0
Use printf:
printf("The value is %.0f", x)
For a description of the format string, see this page from the Java SE 6 API documentation.
Note that you can ofcourse also use the Java library from Scala, so other ways to format numbers from Java can also be used from Scala. You can for example use class java.text.DecimalFormat:
val df = new java.text.DecimalFormat("#####")
println(df.format(x))
Starting with Scala 2.10 you can use the f interpolator:
scala> val x: Double = 1
x: Double = 1.0
scala> println(f"$x%.0f")
1
scala> val i = 1
i: Int = 1
scala> println(f"$i%.0f")
1
The use of a "_.0" at the end of floating point numbers is a convention. Just a way to know that the number is actually floating point and not an integer.
If you really need to "to print it the same way it reads it" you may have to rethink the way your code is structured, possibly preserving your input data. If it's just a formatting issue, the easiest way is to convert the values to integers before printing:
val x = 1.0
println(x.toInt)
If some are integers and some are not, you need a bit more code:
def fmt[T <% math.ScalaNumericConversions](n : T) =
if(n.toInt == n) n.toInt.toString else n.toString
val a : Double = 1.0
val b : Double = 1.5
val c : Int = 1
println(fmt(a))
println(fmt(b))
println(fmt(c))
The code above should print:
1
1.5
1
The signature of the fmt method accepts any type that either is a subtype of ScalaNumericConversions or can be converted to one through implicit conversions (so we can use the toInt method).
If you are working with a Double and want to format it as a String without .0 when it's a whole number and with its decimals otherwise, then you could use String::stripSuffix:
x.toString.stripSuffix(".0")
// val x: Double = 1.34 => "1.34"
// val x: Double = 1.0 => "1"
Use type inference, rather than explicit typing.
scala> val xi = 1
xi: Int = 1
scala> val xd = 1.0
xd: Double = 1.0
scala> println(xi)
1
scala> println(xd)
1.0