bitterharvest’s diary

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

Haskell ドリル6 無名関数

1.概略

zipという関数は便利な関数で、二つのリストを要素ごとについにして返してくれる。例えば、奇数のリストと偶数のリストをzipする。即ち、zip [1,3..] [2,4..]すると、[(1,2), (3,4), (5,6),..]となる。

zipWithはzipを拡張した関数で、要素ごとに演算を施して返してくれる。例えば、先ほどの二つのリストで、要素ごとに足し算をして返してもらう場合には、zipWith (+) [1,3..] [2,4..]とする。返ってくるリストは、[3,7,11,...]である。

二つの間に施す演算を自分独自の関数を与えたい場合がある。関数を定義してその名前を与えてもよいのだが、この場限りの時は、zipWithの後に関数を定義すればよい。例えば、二つの数を足す無名関数は(\ x y -> x + y)である(無名関数はもともとλ関数と呼ばれ、\がλに似ているので使われた)。この無名関数で、\ x yはx,yが引数であることを表し、 ->より後が関数の本体である。先ほどの+の代わりに、この無名関数を用いてzipWith (\ x y -> x + y) [1,3..] [2,4..]とすると、先ほどと同じ答えを返してくる。

2.例題

問題:偶数のリストと奇数のリストから、要素ごとに、それぞれの要素を二乗しそれらを足し合わせたリストを作成する。

「二乗しそれらを足し合わせる」という操作は無名関数(\ x y -> x*x + y*y)で実現できる。従って、下図のようになる。
f:id:bitterharvest:20141210052150p:plain

3.問題

次のプログラムの出力を求めなさい。

問題1:

zipWith (\ x y -> x * y) [1,3..] [2,4..]

問題2:

zipWith (\ x y -> x + y) [1,3..] [1,1..]

問題3:リストの長さが違うときは短いリストが尽きるまで行う。

zipWith (\ x y -> x + y) [1,3..] [10,9..1]

問題4:

zipWith (\ x y -> x - y) [1,3..] [2,4..]

問題5:a bsは絶対値である。

zipWith (\ x y -> abs (x - y)) [1,3..] [2,4..]

問題6:sqrtは平方根である。

zipWith (\ x y -> sqrt (x * x + y * y)) [1,3..] [2,4..]

問題7:

zipWith (\ x y -> sqrt x + sqrt y) [1,3..] [2,4..]

問題8:maxは最大の値を選ぶ。

zipWith (\ x y -> max x y) [1,3..] [2,4..]

問題9:minは最小の値を選ぶ。

zipWith (\ x y -> min x y) [1,3..] [2,4..]

問題10:>は大小比較を行う。左側が大きければTrueを返し、そうでなければFalseを返す。

zipWith (\ x y -> x > y) [1,3..] [2,4..]