绑定单个值以便理解

时间:2011-09-30 11:12:06

标签: scala haskell for-comprehension

Learn You a Haskell教程有一个using a let binder in a list comprehension示例:

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

该函数采用高度/重量对列表,并返回超出某个限制的相应体质量指数列表,例如:

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

这里有趣的是,在理解中绑定的值bmi可以在保护和结果表达式中使用。我知道如何在Scala中执行类似操作的唯一方法是写:

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

我必须在Some包裹我的价值感觉不对。谁知道更好的方法?

2 个答案:

答案 0 :(得分:13)

是的,有这样的语法。

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

单线替代(但不理解):

calcBmis.map(wh => wh._1/(wh._2*wh._2)).filter(_>=25.0)

答案 1 :(得分:1)

我刚刚复制了om-nom-nom的答案,以展示你如何使用花括号而不用分号来表达它。这种方式更清晰

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

而不是使用元组,我使用case表达式(再次,需要大括号)

xs map {case (w, h) => w / (h * h)} filter {_ >= 25.0}