在 for 理解中绑定单个值

发布于 2024-12-07 12:39:15 字数 743 浏览 0 评论 0原文

学习 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 中感觉不对。有人知道更好的方法吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

独夜无伴 2024-12-14 12:39:15

是的,有这样的语法。

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)

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)
花间憩 2024-12-14 12:39:15

我刚刚复制了 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}

I've just copied om-nom-nom's answer to show how you can lay it out using curly braces without the semicolons; it's a bit clearer this way

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

and instead of using tuples, I'd use a case expression (again, requires curly braces)

xs map {case (w, h) => w / (h * h)} filter {_ >= 25.0}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文