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)で実現できる。従って、下図のようになる。
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..]