fugafuga.write

日々のログ

すごいH本 part21

続・畳み込みのコーナー

foldl1 と foldr1

foldl と foldr に似ているが、初期アキュムレータを明示的に与える必要がない

最大値を求める maximum を実装すゆ

maximum' :: (Ord a) => [a] -> a
maximum' = foldl1 max

実行結果

*Main> maximum' [1,2,3,4,5]
5

foldl1 と foldr1 で定義した関数は、引数のリストに少なくとも1つ要素が含まれていることを前提にしているので、空リストに対して呼び出すとランタイムエラーが発生する。一方、foldl と foldr で定義した関数は空リストに対しても正しく動く。

畳み込みの例

reverse を実装

reverse' :: [a] -> [a]
reverse' = foldl (flip (:)) []

実行結果

*Main> reverse' [1,2,3,4,5]
[5,4,3,2,1]

product を実装

product' :: (Num a) => [a] -> a
product' = foldl1 (*)

実行結果

*Main> product' [1,2,3,4]
24

filter を実装

filter' :: (a -> Bool) -> [a] -> [a]
filter' p = foldr (\x acc -> if p x then x : acc else acc) []

実行結果

*Main> filter' (>2) [1,2,3,4]
[3,4]

last を実装する

last' :: [a] -> a
last' = foldl1 (\_ x -> x)

実行結果

*Main> last' [1,2,3,4]
4

所感

maximum'が引数をとらないのは、foldl1 max がリストを引数に取る関数を返すからか...20分くらい悩んだ...

部分適用の頭がまだできてないな。まあ、あんまり気張らずやっていこう。

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

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

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