fugafuga.write

日々のログ

すごいH本 part11

let 式

  • どこでも変数を束縛できる
  • let 式が作る束縛は局所的でガード間で共有されない
  • パターンマッチが使える

cylinder :: Double -> Double -> Double
cylinder r h =
    let sideArea = 2 * pi * r * h
        topArea = pi * r ^ 2
    in  sideArea + 2 * topArea

let <bindings> in <expression>と書く。 letで定義した変数はlet式全体から参照できる。

letwhereの違いは、

  • letは式なのでコード中のどんな場所でも使える
  • whereは節なので指定された使い方しかできない

*Main> 4 * (let a = 9 in a + 1) + 2
42

let の便利な使い方

ローカルスコープに変数を作る

*Main> [let square x = x * x in (square 5, square 3, square 2)]
[(25,9,4)]

セミコロンで区切ることができる

*Main> (let a = 100; b = 200; c = 300 in a * b * c, let foo = "Hey "; bar = "there!" in foo ++ bar)
(6000000,"Hey there!")

パターンマッチでタプルを分解して束縛

*Main> (let (a, b, c) = (1, 2, 3) in a + b + c) * 100
600

リスト内包表記での let

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

let で定義された名前は、出力部分(|より前の部分)とletで定義された部分以降の内包表記すべてから参照できる。 (w, h) <- xsはジェネレータと呼ばれる。この場合ジェネレーターからは名前が参照できない。

フィルタありの場合はこんな感じになる

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

GHCi での let

GHCi での let は in を省略できる。in を書いた場合は即時評価される。

*Main> let zoot x y z = x * y + z
*Main> zoot 3 9 4
31
*Main> let boot x y z = x * y + z in boot 3 5 1
16

所感

内包表記がだんだん複雑になってきてつらい

今日はここまで

すごいHaskellたのしく学ぼう!

すごいHaskellたのしく学ぼう!

  • 作者: MiranLipovaca
  • 出版社/メーカー: オーム社
  • 発売日: 2017/07/14
  • メディア: Kindle版
  • 購入: 4人 クリック: 9回
  • この商品を含むブログを見る