Haskellの標準ライブラリに、高階関数mapってあります。
mapの型定義と機能
型定義 map :: (a -> b) -> [a] -> [b]
引数で与えられた関数をリストの要素すべてに適用する。
ex.
Prelude> map (+100) [1,2,3,4]
[101,102,103,104]
mapの機能拡張とその型定義
mapを機能拡張してみます。
指定条件を満たすリストの要素のみを、mapに引き渡す関数の引数にするとします。
型定義 map_ext' :: (a -> b) -> [a] -> (a -> Bool) -> [b]
ex.リストの要素が偶数のみmapの対象にする
Prelude> map_ext' (+100) [1,2,3,4,5] (even)
[102,104]
標準ライブラリのmapを利用して、mapの機能を拡張しても良いですが、
暇だし、標準ライブラリのfilterを再定義(filter')、ついで、mapを再定義(map')してみます。
まずは、その前にfilterの定義と機能を記載します。
filterの型定義と機能
型定義 filter :: (a -> Bool) -> [a] -> [a]
引数で与えられた述語をリストの要素すべてに適用し、リストを生成する。
ex. 与えられたリストから偶数のリストを作成する
Prelude> filter (even) [1,2,3,4]
[2,4]
はい。では、
map'と、filter'を組み合わせて、mapの機能拡張と洒落込みます。
最初に、map'。
mapの再帰による再定義
リストの要素一つ一つを、引数として得た関数に適用させ、consします。
これを、空リストになるまで繰り返します。
再帰によるmapの再定義
map' :: (a -> b) -> [a] -> [b]
map' f [] = []
map' f (x:xs) = f x : map' f (xs)
ついで、filterの再定義
filterの再帰による再定義
リストの要素一つ一つを、引数として得た述語に適用させ、結果が真のとき、consします。
これを、空リストになるまで繰り返します。
再帰によるfilterの再定義
filter' :: (a -> Bool) -> [a] -> [a]
filter' p [] = []
filter' p (x:xs)
| p x = x : filter' p (xs)
| otherwise = filter' p (xs)
mapの機能拡張、map'とfilter'による再定義
filter'を適用し、得たリストに対し、map'を適用します。
mapの機能拡張
map_ext' :: (a -> b) -> [a] -> (a -> Bool) -> [b]
map_ext' f [] p = []
map_ext' f (xs) p =
let list = filter' p (xs) in map' f list
出来ました。