Why are my Scala types not matching?
Question
I have the following variable series
:
var series: List[FlotSerie] = List(
new FlotSerie() {
override val label = Full("Min")
},
new FlotSerie() {
override val label = Full("Max")
},
new FlotSerie() {
override val label = Full("Avg")
}
)
Unfortunately, I am getting a compiler error with the following method, which takes a new data point and updates series
with a new List[FlotSeries]
based upon the new data and the old series.
def updateSeries(sample: Sample): List[FlotSerie] = {
series = series.map(serie =>
serie match {
case item if item.label == Full("Min") => {
new FlotSerie() {
override val label = item.label
override val data = (sample.timestamp.toDouble, sample.min) :: serie.data
}
}
case item if item.label == Full("Max") => {
new FlotSerie() {
override val label = item.label
override val data = (sample.timestamp.toDouble, sample.max) :: serie.data
}
}
case item if item.label == Full("Avg") => {
new FlotSerie() {
override val label = item.label
override val data = (sample.timestamp.toDouble, sample.avg) :: serie.data
}
}
}
)
}
The Scala compiler chokes on the reassignment because it finds a type mismatch:
error: type mismatch;
found : Unit
required: List[net.liftweb.widgets.flot.FlotSerie]
series = series.map(serie => serie match {
What am I doing wrong here? It seems like it should be returning a List[FlotSeries] that can be assigned to series
. Since the compiler finds Unit
I thought of how foreach
always returns Unit
, I am but the match
operator returns the last value of the matched expression, not Unit
.
Solution
Assignments in Scala return Unit (aka Scala's not quite null null), unlike Ruby which returns the assigned value. Your method is attempting to return Unit instead of List[FlotSerie].
Add:
return series
to your method, or change it to return Unit.
You could also simplify your code using case classes and proper matching if it's appropriate:
case class FlotSerie(label:Full, data:List[Tuple2[Double, Double]])
var series: List[FlotSerie] = List( FlotSerie(Full("Min"), Nil), FlotSerie(Full("Max"), Nil), FlotSerie(Full("Avg"), Nil) )
def updateSeries(sample: Sample): List[FlotSerie] = {
series = series.map(serie => {
serie.label match {
case Full("Min") => FlotSerie(serie.label, (sample.timestamp.toDouble, sample.min) :: serie.data)
case Full("Max") => FlotSerie(serie.label, (sample.timestamp.toDouble, sample.max) :: serie.data)
case Full("Avg") => FlotSerie(serie.label, (sample.timestamp.toDouble, sample.avg) :: serie.data)
}
})
return series
}
I'm pretty new to Scala myself so YMMV.
OTHER TIPS
remove series =
you're assigned the map function to series and not returning anything.