fugafuga.write

日々のログ

すごいH本 part17

便利な関数

map

関数とリストを受け取ってその関数をリスト全ての要素に適用して新しいリストを生成する。

*Main> :t map
map :: (a -> b) -> [a] -> [b]

実装

map' :: (a -> b) -> [a] -> [b]
map' _ [] = []
map' f (x:xs) = f x : map' f xs

実行

*Main> map' (+3) [1,2,3,4,5]
[4,5,6,7,8]
*Main> map' (replicate 3) [1..3]
[[1,1,1],[2,2,2],[3,3,3]]
*Main> map' (map' (^2)) [[1,2],[3,4,5,6],[7,8]]
[[1,4],[9,16,25,36],[49,64]]

リストの内包表記でも同じことができるが、map を使うほうが読みやすくなる。

[x + 3 | x <- [1,2,3,4,5]]

filter

述語とリストを受け取り、そのリストの要素のうち、述語をみたすもののみからなるリストを返す。

*Main> :t filter
filter :: (a -> Bool) -> [a] -> [a]

実装

filter' :: (a -> Bool) -> [a] -> [a]
filter' _ [] = []
filter' p (x:xs)
  | p x       = x : filter' p xs
  | otherwise = filter' p xs

実行結果

*Main> filter' (>5) [1,2,3,4,5,6]
[6]
*Main> let notNull x = not (null x) in filter' notNull [[1,2,3],[],[3,4,5],[2,2],[],[],[]]
[[1,2,3],[3,4,5],[2,2]]
*Main> filter' even [1,2,3,4,5]
[2,4]

クイックソートの関数をfilter使って書き直す

quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort (x:xs) =
    let smallerOrEqual = filter (<= x) xs
        larger = filter (> x) xs
    in  quicksort smallerOrEqual ++ [x] ++ quicksort larger

内包表記つかうか、map, filter 関数使うかは読みやすいかどうかで決めてよい。

所感

map, filter なんかは Ruby で出てきたりするのでなんとなくわかる。が Haskell で書くのは慣れが必要だと感じる。

すごいHaskellたのしく学ぼう!

すごいHaskellたのしく学ぼう!

  • 作者: MiranLipovaca
  • 出版社/メーカー: オーム社
  • 発売日: 2017/07/14
  • メディア: Kindle版
  • 購入: 4人 クリック: 9回
  • この商品を含むブログを見る