Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding a single value within a for comprehension

The Learn You a Haskell tutorial has an example of using a let binder in a list comprehension:

calcBmis xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2, bmi >= 25.0]

The function takes a list of height/weight pairs, and returns a list of the corresponding body-mass indices that exceed some limit, eg:

ghci> calcBmis [(70, 1.85), (50, 2.00), (130, 1.62)]
[49.53513183965858]

What's interesting to me here is that the value bmi that is bound within the comprehension can be used both in a guard and in the resulting expression. The only way I know how to do something similar in Scala is to write:

def calcBmis(xs : Seq[(Double,Double)]) =
  for((w,h) <- xs ; bmi <- Some(w / (h*h)) if bmi >= 25.0) yield bmi

Having to wrap my value in a Some here feels wrong. Anyone knows of a better way?

like image 787
Philippe Avatar asked Dec 10 '22 05:12

Philippe


1 Answers

Yes, there is such syntax.

def calcBmis(xs : Seq[(Double,Double)]) =
  for((w,h) <- xs ; bmi = w / (h*h); if bmi >= 25.0) yield bmi

One-liner alternative (but not comprehension):

calcBmis.map(wh => wh._1/(wh._2*wh._2)).filter(_>=25.0)
like image 90
om-nom-nom Avatar answered Dec 26 '22 06:12

om-nom-nom