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 に答える