4

Learn You a Haskell教程有一个在列表理解中使用let活页夹的示例:

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这里包装我的价值感觉是错误的。有人知道更好的方法吗?

4

2 回答 2

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)
于 2011-09-30T11:15:37.503 回答
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}
于 2011-09-30T21:11:04.473 回答