I am trying to solve a "simple" exercise in Scala. I have this function:
def mean(xs: Seq[Double]): Option[Double] =
if (xs.isEmpty) None
else Some(xs.sum / xs.length)
This is the text of the exercise:
EXERCISE 2: Implement the variance function (if the mean is m , variance is the mean of math.pow(x - m, 2) , see definition ) in terms of mean and flatMap .
I was thinking something like
val xs = List(1.3,2.1,3.2)
val m = mean(xs)
xs flatMap(x=> math.pow(x-m,2)).mean //error!
What is the right way to solve? If possible I would like also a small theoretical explanation
I wouldn't call this simple.
map
on Option[A]
takes a function A => B
and returns an Option[B]
which is a Some
if the original was a Some
, and None
otherwise. So Some(2).map(_+2)
gives Some(4)
, but None[Int].map(_+2)
gives None.
flatMap
is much the same, but it takes a function A => Option[B]
and still returns an Option[B]
. If the original is None
or the given function results in None
, the result is None
otherwise it's a Some[B]
.
You don't want to flatMap
over the list, you want to flatMap
the option. I'll give you a hint, it starts with:
mean(xs).flatMap(m => ...
After that arrow, m
is a Double
, not an Option[Double]
.
Edit:
Alright, fine, since we're getting all downvotey and not being helpful, here's the full answer:
def variance(xs: Seq[Double]): Option[Double] = {
mean(xs).flatMap(m => mean(xs.map(x => Math.pow(x-m, 2))))
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With