Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: How do I calculate the variance of a Seq[Double] using flatMap and Options?

Tags:

scala

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

like image 438
Donbeo Avatar asked Feb 27 '15 19:02

Donbeo


1 Answers

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))))
}
like image 181
MattPutnam Avatar answered Nov 15 '22 08:11

MattPutnam