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
在这里感觉不对。有人知道更好的方法吗?
是的,有这样的语法。
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)
我只是复制了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}