プログラミングHaskell (第四章の練習問題)

in

4.8 (1) 偶数の長さをもつリストを半分に分割するhalve::[a] -> ([a],[a])を定義せよ

havle::[a] -> ([a],[a])
havle xs = (take n xs, drop n xs)
where n = length xs `div` 2

リストの長さが奇数でもOKだが?例外をスローすべきなのか?この章までではエラー処理についてはなにも言及されていないのでこのままで。解答には、

halve xs = splitAt (length xs `div` 2) xs

というのもありました。通常、こちらを使うべきですね。

4.8 (2) 空リストを与えてもエラーとならないsafetail::[a] -> [a]を条件式,ガード付き等式,パターンマッチでそれぞれ定義せよ。

safetail_a::[a] -> [a]
safetail_a xs = if null xs then [] else tail xs

safetail_b::[a] -> [a]
safetail_b xs | null xs = []
              | otherwise = tail xs

safetail_c::[a] -> [a]
safetail_c [] = []
safetail_c xs = tail xs

解答では、パターンマッチの引数の書き方をxs,(x:xs)の二種類示してあって、

safetail_c::[a] -> [a]
safetail_c [] = []
safetail_c (x:xs) = xs

tailを使わないパタンの方が簡潔な気がするので減点。

4.8 (3) パターンマッチを用いて論理和演算子(∨)を四通りの方法で定義せよ

a1::Bool -> Bool -> Bool
a1 False False = False
a1 True  False = True
a1 False True  = True
a1 True  True  = True

a2::Bool -> Bool -> Bool
a2 False False = False
a2 _  _ = True

a3::Bool -> Bool -> Bool
a3 True _ = True
a3 _ True = True
a3 _ _    = False

a4::Bool -> Bool -> Bool
a4 False  x = x
a4 x  False = x
a4 _ _      = True

これもそれほど難しくはないと思いますが、a1の定義などはどう考えても冗長なわけでパターンマッチの勉強というよりも、"どのように書くのがもっとも適切であるか"を常に考えさせるのが目的のように思えます。

解答では演算子で書いていますが、意味があっているのOKとします。ところで解答には、

b ∨ c | b == c = b
      | otherwise = True

これ、反則?ガード式じゃん!ねー。問題は"パターンマッチを用いて四通り"なのにぃ。こっちだって、a4ひねり出すのに苦労したんだからっ!よって、勝手ながらボーナスポイントを付加します。

4.8 (4)(5) 以下の論理演算子を条件式を使って定義せよ。以下も同様にせよ

b1::Bool -> Bool -> Bool
b1 x y = if x
then if y
then True
else False
else False

c1::Bool -> Bool -> Bool
c1 x y = if x then y else False

これも3.と同様、どちらが簡潔ですか?を問う問題かな?

4.8 (6) カリー化された関数 mult x y z = x * y * zはλ式を用いるとどのように表現できるかを示せ

mult::Num a => a -> a -> a -> a
mult = \x -> (\y -> (\z -> x * y * z))

これはもう、コメントできるほど理解できていないかも。とりあず、"このように書く"というレベル。今後の章を追って勉強を進めていきながら身につけたいです。

添付サイズ
ex4.hs1021 bytes

この記事のトラックバックURL:

http://hippos-lab.com/blog/trackback/350

Comments