bitterharvest’s diary

A Bitter Harvestは小説の題名。作者は豪州のPeter Yeldham。苦闘の末に勝ちえた偏見からの解放は命との引換になったという悲しい物語

Haskell ドリル11 局所変数

1.概略

長いプログラムを書いていると、一時的に変数を使いたいときがある。そのようなことを可能にしてくれるのが、letとwhereである。

まず、letから説明する。letは次の四つの場面で使用することができる。
1.ローカルスコープで関数を作成する。

Prelude> [let absolute x = if x >=0 then x else (- x) in (absolute (-4.5), absolute (-3.2), absolute 4)]
[(4.5,3.2,4)]

2.セミコロンを区切りに使える。

Prelude> let a = 10; b = 20; c = 30 in a + b + c
60

3.パターン照合で変数を束縛できる。

Prelude> let (a, b, c, d) = ("I ", "was ", "a ", "baby.") in a ++ b ++ c ++ d
"I was a baby."

4.内包表記の中でも使用できる。

Prelude> [ (a, b) | a <- [1..5], let b = a * a]
[(1,1),(2,4),(3,9),(4,16),(5,25)]

次にwhereについて説明する。
whereは次のような場合に使用する。

1.同じ計算を繰り返し使用する。

Prelude> let ratio a b c = (a / total, b / total, c /total) where total = a + b + c
Prelude> ratio 3 5 7
(0.2,0.3333333333333333,0.4666666666666667)

2.関数を呼ぶ。

例えば、直方体の表面積 surface を得ることを考える。これは、直方体を構成している表面の直方形の面積areaを加えればよいので次のようになる。

Prelude> let surface a b c = (area a b) * 2 + (area b c) * 2 + (area c a) * 2 where area x y = x * y 
Prelude> surface 2 3 4
52

2.問題

それでは問題を解いてみる。

問題1:三回の試験結果がタプルで与えられた時、その合計が、80点以上であればA、70点以上から79点までであればB、60点以上から69点までであればC、それ以外をDとして返す関数をletを用いて表しなさい。

問題2:問題1をwhereを用いて解きなさい。

問題3:自然数のリストが与えられた時、元の数とその三乗を対にしたリストを返すような内包表記をletを用いて作成しなさい。

問題4:問題3をwhereを用いた場合にはどのように解けるかを説明しなさい。

問題5:肥満度は、キログラムで表した体重を、メートルで表した身長の二乗で割った体格指数 BMI (Body Mass Index)で表される。BMIが18.5未満を低体重(Light)、25以上を肥満(Fat)、それ以外を普通(Normal)という。身長と体重が与えられた時、肥満度を計算する関数をletを用いて作成しなさい。

問題6:問題5をwhereを用いて解きなさい。

問題7:5人で食事をした。それぞれ別々の料理を頼んだので食事代が異なっていた。全体の食事代に占めるそれぞれの人の食事代の割合を知りたくなった。これを求める関数をletを用いて表しなさい。

問題8:問題7をwhereを用いて解きなさい。

問題9:一片の長さがaである正三角形、正四角形、正六角形の面積をタプルで出力する関数をletを用いて表しなさい。

問題10:問題9をwhereを用いて解きなさい。