Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
λfunctional
presented by @s_kozake
map / filter / foldl / foldr
in
こわくないよたのしい高階関数          λ                発表をする          ▲               資料をつくる              資料をあきらめる
たのしい高階関数 λ  目的本勉強会の趣旨   本セッションは高階関数入門です   関数型言語の視野を拡げ、たのしく   使っていくことを目的としております。
つまりですね
たのしい高階関数 λ  目的本勉強会の趣旨   本セッションは高階関数入門です   関数型言語の視野を拡げ、たのしく   使っていくことを目的としております。
大事なことなので2回いいました
たのしい高階関数 λ  注意事項
たのしい高階関数 λ  関数型言語は怖いイメージがあるみたいですが
たのしい高階関数 λ       当セッションはイージーモードです。
たのしい高階関数 λ         モナド / ファンクタ / 遅延評価 / 圏論 / 論証                ダメ。ゼッタイ。               「みんなやってる」なんて理由にならない
プログラマたちは ぜんめつしました。このような悲劇を繰り返さないためにもね
たのしく学びましょう~
たのしい高階関数 λ  自己紹介   Java    ★★☆   Scala ☆☆☆   Haskell ☆☆☆   そろそろ Scala で仕事したいです。   アストルティア   Twitter@s_kozake
たのしい高階関数 λ  Agenda                 高階関数ってなに?                     高階関数を学ぶメリット                 リストを扱う高階関数               まとめ
たのしい高階関数 λ  Agenda                 高階関数ってなに?                     高階関数を学ぶメリット                 リストを扱う高階関数               まとめ
たのしい高階関数 λ  高階関数ってなに?   引数として関数を取ったり、   返り値として関数を返したりする関数   関数型言語では、   関数がファーストクラスオブジェクト   として扱える。
たのしい高階関数 λ  高階関数ってなに?   ファーストクラスオブジェクトとは   ・無名のリテラルとして表現可能   ・変数に格納可能   ・データ構造への組み込みが可能   ・プロシージャや関数のパラメータとして渡すことができる   ・プ...
たのしい高階関数 λ  高階関数ってなに?   def twice(f:(Int => Int))(x:Int):Int = f(f(x))
たのしい高階関数 λ  高階関数ってなに?   def twice(f:(Int => Int))(x:Int):Int = f(f(x))関数 twice はInt 型の引数を受け取り Int 型の値を返す関数 fを受け取り、Int 型の引数...
たのしい高階関数 λ  高階関数ってなに?   def twice(f:(Int => Int))(x:Int):Int = f(f(x))   def add1(x:Int) = x + 1   > val add2 = twice(add1...
たのしい高階関数 λ  高階関数ってなに?   def twice(f:(Int => Int))(x:Int):Int = f(f(x))   def add1(x:Int) = x + 1                          ...
たのしい高階関数 λ  高階関数ってなに?   def twice(f:(Int => Int))(x:Int):Int = f(f(x))   def add1(x:Int) = x + 1   > val add2 = twice(add1...
たのしい高階関数 λ  Agenda                 高階関数ってなに?                     高階関数を学ぶメリット                 リストを扱う高階関数               まとめ
たのしい高階関数 λ  高階関数を学ぶメリット          処理の再利用の行いやすさ          処理の再利用の行いやすさ          パターンとしての高階関数          パターンとしての高階関数
たのしい高階関数 λ  高階関数を学ぶメリット          処理の再利用の行いやすさ          処理の再利用の行いやすさ          パターンとしての高階関数          パターンとしての高階関数
たのしい高階関数 λ  高階関数を学ぶメリット               例えば、ある関数 a の大部分が      関数 a     共通処理で、一部が個別処理の場合     共通処理               例 ) ファイルの Ope...
たのしい高階関数 λ  高階関数を学ぶメリット                 ● 値渡しによる処理の分岐     関数 a(x)     共通処理        ・個別処理が増える度に、                  関数の処理が増大する...
たのしい高階関数 λ  高階関数を学ぶメリット抽象クラス A                 ● 個別処理の抽象化     メソッド a      ( template method パターン)     共通処理                ...
たのしい高階関数 λ  高階関数を学ぶメリット                ● 関数渡しによる処理の再利用      関数 a(f)                ・個別処理が増えても     共通処理                 関数本...
たのしい高階関数 λ  高階関数を学ぶメリット                  関数を組み合わせて新しい関数を     関数 a(f)(x)   作るのも容易     共通処理                  +   個別処理 11    ...
ん?
インターフェース渡しがあるじゃん!
たのしい高階関数 λ  高階関数を学ぶメリット  例えば、あるリストの値を 2 倍した結果、  10 以上のものを抜き出して全部足した値を求める場合。      list.map(_ * 2).filter(_ >= 10).reduce(_ ...
たのしい高階関数 λ  高階関数を学ぶメリット   list.map(new Func1<Integer, Integer>() {       public Integer apply(Integer a) { return a * 2;} ...
やってられるか~!!
たのしい高階関数 λ  高階関数を学ぶメリット          処理の再利用の行いやすさ          処理の再利用の行いやすさ  ・高階関数は関数を引数に渡せるので、   処理の再利用が行いやすい  ・但し、型推論、ラムダ式など、手軽に...
たのしい高階関数 λ  高階関数を学ぶメリット          処理の再利用の行いやすさ          処理の再利用の行いやすさ          パターンとしての高階関数          パターンとしての高階関数
たのしい高階関数 λ  高階関数を学ぶメリット  例えば、リストの全ての要素に関数を写す関数は map      List(1,2,3).map(_ * 2)     map (*2) [1,2,3]     JavaScript     [1...
たのしい高階関数 λ  高階関数を学ぶメリット  例えば、 Scala の flatMap はモナドの bind と分かれば  以下の動作が容易に推測できる。   > List(1,2,3).flatMap(x => List(x*2))   ...
たのしい高階関数 λ  高階関数を学ぶメリット          パターンとしての高階関数          パターンとしての高階関数  ・関数型言語にはパターンがある。  ・パターンを覚えれば、他の関数型言語でも応用が利く。
たのしい高階関数 λ  Agenda                 高階関数ってなに?                     高階関数を学ぶメリット                 リストを扱う高階関数               まとめ
たのしい高階関数 λ  リストを扱う高階関数               map 関数               map 関数               filter 関数                filter 関数         ...
たのしい高階関数 λ  リストのおさらい    0 :: 1 :: 2 :: 3 :: Nil    0 : 1 : 2 : 3 : []                                        []           ...
たのしい高階関数 λ  リストのおさらい   つまりですね
たのしい高階関数 λ  リストのおさらい   こんなイメージ   ヘッダ         テイル                     ラスト   Nil
たのしい高階関数 λ  リストを扱う高階関数               map 関数               map 関数               filter 関数                filter 関数         ...
たのしい高階関数 λ  リストを扱う高階関数   map 関数のイメージ     [1,2,3,4 ・・ ,n]                map f     [f(1), f(2), f(3), f(4) ・・ ,f(n)]   関数 f...
たのしい高階関数 λ  リストを扱う高階関数   こういう風に使います     let ベホマラー = map ベホイミ     let ルカナン = map ルカニ     let スクルト = map スカラ
たのしい高階関数 λ  リストを扱う高階関数   map 関数の例     > map (x -> x * 2) [1,2,3]     [2,4,6]     > map (x -> "hoge" ++ show(x)) [1,2,3]   ...
たのしい高階関数 λ  リストを扱う高階関数   map 関数の実装       map :: (a -> b) -> [a] -> [b]       map _ [] = []       map f (x:xs) = f x : map ...
たのしい高階関数 λ  リストを扱う高階関数   map 関数の実装      def map[B, That](f: A => B)                        (implicit bf: CanBuildFrom[Repr...
たのしい高階関数 λ  リストを扱う高階関数   map 関数の実装(簡略化)      def map[B, That](f: A => B)        def map[A, B](f: A => Bbf:List[B] = {     ...
たのしい高階関数 λ  リストを扱う高階関数               map 関数               map 関数               filter 関数                filter 関数         ...
たのしい高階関数 λ  リストを扱う高階関数   filter 関数のイメージ     [1,2,3,4 ・・ ,n]                   filter (x => x < 4)     [1,2,3]   関数 f で要素を篩...
たのしい高階関数 λ  リストを扱う高階関数   こういう時に使います ゲームしばり無視していますが。。  let レベル 5 デス = filter (not . is レベル 5)
たのしい高階関数 λ  リストを扱う高階関数   filter 関数の例  > filter (x -> not(x `mod` 5 == 0)) [3,4,5,10,12]  [3,4,12]
たのしい高階関数 λ  リストを扱う高階関数   filter 関数の実装     filter :: (a -> Bool) -> [a] -> [a]     filter _pred []    = []     filter pred ...
たのしい高階関数 λ  リストを扱う高階関数   filter 関数の実装     def filter(p: A => Boolean): Repr = {       val b = newBuilder       for (x <- t...
たのしい高階関数 λ  リストを扱う高階関数               map 関数               map 関数               filter 関数                filter 関数         ...
たのしい高階関数 λ  リストを扱う高階関数   foldl / foldr 関数のイメージ  foldl f 0 [1,2,3,4]   foldr f 0 [1,2,3,4]               f                f...
たのしい高階関数 λ     一応やっときます
たのしい高階関数 λ     右も左もないですが         +     +       +   +                   =
たのしい高階関数 λ  リストを扱う高階関数   foldl / foldr 関数の例     > let add x y = x + y     > foldl add 0 [1,2,3,4]     10     > foldr add 0...
たのしい高階関数 λ  リストを扱う高階関数   foldl / foldr 関数の例     > let add x y = x + y     > foldl add 0 [1,2,3,4]     = add(add(add(add(0,...
たのしい高階関数 λ  リストを扱う高階関数   foldl / foldr 関数の例     > let add x y = x + y     > foldl add 0 [1,2,3,4]     10     >   foldr add...
たのしい高階関数 λ  リストを扱う高階関数   foldr 関数の実装     foldr :: (a -> b -> b) -> b -> [a] -> b     foldr k z = go               where   ...
たのしい高階関数 λ  リストを扱う高階関数   foldr 関数の実装     foldr :: (a -> b -> b) -> b -> [a] -> b     foldr k z = go               where   ...
たのしい高階関数 λ  リストを扱う高階関数   foldl 関数の実装     foldl :: (a -> b -> a) -> a -> [b] -> a     foldl f z0 xs0 = lgo z0 xs0          ...
たのしい高階関数 λ  リストを扱う高階関数   foldl 関数の実装     foldl :: (a -> b -> a) -> a -> [b] -> a     foldl f z0 xs0 = lgo z0 xs0          ...
たのしい高階関数 λ  リストを扱う高階関数   foldLeft 関数の実装 (Scala)     def foldLeft[B](z: B)(f: (B, A) => B): B = {       var acc = z       v...
たのしい高階関数 λ  リストを扱う高階関数   foldRight 関数の実装 (Scala)     def foldRight[B](z: B)(f: (A, B) => B): B =       if (this.isEmpty) z...
たのしい高階関数 λ  リストを扱う高階関数   Scala の foldRight 関数の注意点     scala> (1 to 10000).toList.foldLeft(0)(_ + _)     res0: Int = 500050...
たのしい高階関数 λ  リストを扱う高階関数   Range の場合は大丈夫     scala> (1 to 10000).foldLeft(0)(_ + _)     res0: Int = 50005000     scala> (1 t...
たのしい高階関数 λ  リストを扱う高階関数   Range の foldRight 関数の実装     def foldRight[B](z: B)(op: (A, B) => B): B =       reversed.foldLeft(...
たのしい高階関数 λ  Agenda                 高階関数ってなに?                     高階関数を学ぶメリット                 リストを扱う高階関数               まとめ
たのしい高階関数 λ    ・高階関数は関数を引数に渡せるので、処理の再利用が   行いやすい(型推論やラムダ式などの言語支援が重要)  ・パターンを覚えると、他の関数型言語でも応用が利く  ・リスト処理の高階関数のように、便利で強力な関数が ...
ご清聴ありがとうございました!!
たのしい高階関数
Upcoming SlideShare
Loading in …5
×

たのしい高階関数

10,690 views

Published on

第2回関数型勉強会 in 大阪
で使った資料です。

Published in: Technology
  • Be the first to comment

たのしい高階関数

  1. 1. λfunctional
  2. 2. presented by @s_kozake
  3. 3. map / filter / foldl / foldr
  4. 4. in
  5. 5. こわくないよたのしい高階関数 λ 発表をする ▲ 資料をつくる 資料をあきらめる
  6. 6. たのしい高階関数 λ  目的本勉強会の趣旨 本セッションは高階関数入門です 関数型言語の視野を拡げ、たのしく 使っていくことを目的としております。
  7. 7. つまりですね
  8. 8. たのしい高階関数 λ  目的本勉強会の趣旨 本セッションは高階関数入門です 関数型言語の視野を拡げ、たのしく 使っていくことを目的としております。
  9. 9. 大事なことなので2回いいました
  10. 10. たのしい高階関数 λ  注意事項
  11. 11. たのしい高階関数 λ  関数型言語は怖いイメージがあるみたいですが
  12. 12. たのしい高階関数 λ   当セッションはイージーモードです。
  13. 13. たのしい高階関数 λ   モナド / ファンクタ / 遅延評価 / 圏論 / 論証 ダメ。ゼッタイ。 「みんなやってる」なんて理由にならない
  14. 14. プログラマたちは ぜんめつしました。このような悲劇を繰り返さないためにもね
  15. 15. たのしく学びましょう~
  16. 16. たのしい高階関数 λ  自己紹介 Java ★★☆ Scala ☆☆☆ Haskell ☆☆☆ そろそろ Scala で仕事したいです。 アストルティア Twitter@s_kozake
  17. 17. たのしい高階関数 λ  Agenda 高階関数ってなに? 高階関数を学ぶメリット リストを扱う高階関数 まとめ
  18. 18. たのしい高階関数 λ  Agenda 高階関数ってなに? 高階関数を学ぶメリット リストを扱う高階関数 まとめ
  19. 19. たのしい高階関数 λ  高階関数ってなに? 引数として関数を取ったり、 返り値として関数を返したりする関数 関数型言語では、 関数がファーストクラスオブジェクト として扱える。
  20. 20. たのしい高階関数 λ  高階関数ってなに? ファーストクラスオブジェクトとは ・無名のリテラルとして表現可能 ・変数に格納可能 ・データ構造への組み込みが可能 ・プロシージャや関数のパラメータとして渡すことができる ・プロシージャや関数の戻り値として返すことができる
  21. 21. たのしい高階関数 λ  高階関数ってなに? def twice(f:(Int => Int))(x:Int):Int = f(f(x))
  22. 22. たのしい高階関数 λ  高階関数ってなに? def twice(f:(Int => Int))(x:Int):Int = f(f(x))関数 twice はInt 型の引数を受け取り Int 型の値を返す関数 fを受け取り、Int 型の引数を受け取り Int 型の値を返す関数を返す関数
  23. 23. たのしい高階関数 λ  高階関数ってなに? def twice(f:(Int => Int))(x:Int):Int = f(f(x)) def add1(x:Int) = x + 1 > val add2 = twice(add1)(_) add2: Int => Int = <function1> > add2(3) res1: Int = 5
  24. 24. たのしい高階関数 λ  高階関数ってなに? def twice(f:(Int => Int))(x:Int):Int = f(f(x)) def add1(x:Int) = x + 1 Int 型の引数を受け取り Int 型の値を返す関数 > val add2 = twice(add1)(_) add2: Int => Int = <function1> Int 型の引数を受け取り > add2(3) Int 型の値を返す関数 res1: Int = 5
  25. 25. たのしい高階関数 λ  高階関数ってなに? def twice(f:(Int => Int))(x:Int):Int = f(f(x)) def add1(x:Int) = x + 1 > val add2 = twice(add1)(_) add2: Int => Int = <function1> > add2(3) = twice(add1)(3) = add1(add1(3)) res1: Int = 5
  26. 26. たのしい高階関数 λ  Agenda 高階関数ってなに? 高階関数を学ぶメリット リストを扱う高階関数 まとめ
  27. 27. たのしい高階関数 λ  高階関数を学ぶメリット 処理の再利用の行いやすさ 処理の再利用の行いやすさ パターンとしての高階関数 パターンとしての高階関数
  28. 28. たのしい高階関数 λ  高階関数を学ぶメリット 処理の再利用の行いやすさ 処理の再利用の行いやすさ パターンとしての高階関数 パターンとしての高階関数
  29. 29. たのしい高階関数 λ  高階関数を学ぶメリット 例えば、ある関数 a の大部分が 関数 a 共通処理で、一部が個別処理の場合 共通処理 例 ) ファイルの Open/Close   トランザクションの Begin/End 個別処理   リトライ処理    Tree の走査 共通処理
  30. 30. たのしい高階関数 λ  高階関数を学ぶメリット ● 値渡しによる処理の分岐 関数 a(x) 共通処理 ・個別処理が増える度に、  関数の処理が増大する if(x == 1) 個別処理 1 ・関数の引数に制御情報を渡している else  =制御結合 個別処理 2 共通処理
  31. 31. たのしい高階関数 λ  高階関数を学ぶメリット抽象クラス A ● 個別処理の抽象化 メソッド a ( template method パターン) 共通処理 ・処理毎にクラスが増える Call メソッド b 共通処理 抽象メソッド b
  32. 32. たのしい高階関数 λ  高階関数を学ぶメリット ● 関数渡しによる処理の再利用 関数 a(f) ・個別処理が増えても 共通処理  関数本体が複雑にならない 個別処理 f ・関数を値として扱える  =データ結合 共通処理
  33. 33. たのしい高階関数 λ  高階関数を学ぶメリット 関数を組み合わせて新しい関数を 関数 a(f)(x) 作るのも容易 共通処理 + 個別処理 11 個別処理 = 関数 a1(x) 個別処理 f + 個別処理 22 個別処理 = 関数 a2(x) 共通処理 + 個別処理 33 個別処理 = 関数 a(x)
  34. 34. ん?
  35. 35. インターフェース渡しがあるじゃん!
  36. 36. たのしい高階関数 λ  高階関数を学ぶメリット 例えば、あるリストの値を 2 倍した結果、 10 以上のものを抜き出して全部足した値を求める場合。 list.map(_ * 2).filter(_ >= 10).reduce(_ + _) foldr (+) 0 . filter (>=10) . map (*2) $ list
  37. 37. たのしい高階関数 λ  高階関数を学ぶメリット list.map(new Func1<Integer, Integer>() { public Integer apply(Integer a) { return a * 2;} }).filter(new Func1<Integer, Boolean>() { public Boolean apply(Integer a) { return a >= 10;} }).reduce(new Func2<Integer, Integer, Integer>() { public Integer apply(Integer a, Integer b) { return a + b; } });
  38. 38. やってられるか~!!
  39. 39. たのしい高階関数 λ  高階関数を学ぶメリット 処理の再利用の行いやすさ 処理の再利用の行いやすさ ・高階関数は関数を引数に渡せるので、  処理の再利用が行いやすい ・但し、型推論、ラムダ式など、手軽に関数を扱える  言語サポートが備わっていることが重要
  40. 40. たのしい高階関数 λ  高階関数を学ぶメリット 処理の再利用の行いやすさ 処理の再利用の行いやすさ パターンとしての高階関数 パターンとしての高階関数
  41. 41. たのしい高階関数 λ  高階関数を学ぶメリット 例えば、リストの全ての要素に関数を写す関数は map List(1,2,3).map(_ * 2) map (*2) [1,2,3] JavaScript [1,2,3].map(function(a) { return a * 2 })
  42. 42. たのしい高階関数 λ  高階関数を学ぶメリット 例えば、 Scala の flatMap はモナドの bind と分かれば 以下の動作が容易に推測できる。 > List(1,2,3).flatMap(x => List(x*2)) res0: List[Int] = List(2, 4, 6) > Some(1).flatMap(x => Some(x*2)) res1: Option[Int] = Some(2)
  43. 43. たのしい高階関数 λ  高階関数を学ぶメリット パターンとしての高階関数 パターンとしての高階関数 ・関数型言語にはパターンがある。 ・パターンを覚えれば、他の関数型言語でも応用が利く。
  44. 44. たのしい高階関数 λ  Agenda 高階関数ってなに? 高階関数を学ぶメリット リストを扱う高階関数 まとめ
  45. 45. たのしい高階関数 λ  リストを扱う高階関数 map 関数 map 関数 filter 関数 filter 関数 畳込み関数 畳込み関数・神は言われた。「リストあれ」・リストと関数型言語は関連が深い・ Java やってて「あれ欲しい」は たいていリストの高階関数
  46. 46. たのしい高階関数 λ  リストのおさらい 0 :: 1 :: 2 :: 3 :: Nil 0 : 1 : 2 : 3 : [] [] 0 1 2 3 ヘッダ テイル ラスト Nil
  47. 47. たのしい高階関数 λ  リストのおさらい つまりですね
  48. 48. たのしい高階関数 λ  リストのおさらい こんなイメージ ヘッダ テイル ラスト Nil
  49. 49. たのしい高階関数 λ  リストを扱う高階関数 map 関数 map 関数 filter 関数 filter 関数 畳込み関数 畳込み関数
  50. 50. たのしい高階関数 λ  リストを扱う高階関数 map 関数のイメージ [1,2,3,4 ・・ ,n] map f [f(1), f(2), f(3), f(4) ・・ ,f(n)] 関数 f をリストに写す( map over )
  51. 51. たのしい高階関数 λ  リストを扱う高階関数 こういう風に使います let ベホマラー = map ベホイミ let ルカナン = map ルカニ let スクルト = map スカラ
  52. 52. たのしい高階関数 λ  リストを扱う高階関数 map 関数の例 > map (x -> x * 2) [1,2,3] [2,4,6] > map (x -> "hoge" ++ show(x)) [1,2,3] ["hoge1","hoge2","hoge3"]
  53. 53. たのしい高階関数 λ  リストを扱う高階関数 map 関数の実装 map :: (a -> b) -> [a] -> [b] map _ [] = [] map f (x:xs) = f x : map f xs ヘッダ テイル
  54. 54. たのしい高階関数 λ  リストを扱う高階関数 map 関数の実装 def map[B, That](f: A => B) (implicit bf: CanBuildFrom[Repr, B, That]) : That = { val b = bf(repr) b.sizeHint(this) for (x <- this) b += f(x) b.result }
  55. 55. たのしい高階関数 λ  リストを扱う高階関数 map 関数の実装(簡略化) def map[B, That](f: A => B) def map[A, B](f: A => Bbf:List[B] = { (implicit ): CanBuildFrom[Repr, B, That]) val b = new :ListBuffer[B]() That = { val b = bf(repr) b.sizeHint(this) b.sizeHint(this) buff += f(x) for (x <- this) for (x <- this) b += f(x) b.result }b.result }
  56. 56. たのしい高階関数 λ  リストを扱う高階関数 map 関数 map 関数 filter 関数 filter 関数 畳込み関数 畳込み関数
  57. 57. たのしい高階関数 λ  リストを扱う高階関数 filter 関数のイメージ [1,2,3,4 ・・ ,n] filter (x => x < 4) [1,2,3] 関数 f で要素を篩いに掛ける
  58. 58. たのしい高階関数 λ  リストを扱う高階関数 こういう時に使います ゲームしばり無視していますが。。 let レベル 5 デス = filter (not . is レベル 5)
  59. 59. たのしい高階関数 λ  リストを扱う高階関数 filter 関数の例 > filter (x -> not(x `mod` 5 == 0)) [3,4,5,10,12] [3,4,12]
  60. 60. たのしい高階関数 λ  リストを扱う高階関数 filter 関数の実装 filter :: (a -> Bool) -> [a] -> [a] filter _pred [] = [] filter pred (x:xs) | pred x = x : filter pred xs | otherwise = filter pred xs
  61. 61. たのしい高階関数 λ  リストを扱う高階関数 filter 関数の実装 def filter(p: A => Boolean): Repr = { val b = newBuilder for (x <- this) if (p(x)) b += x b.result }
  62. 62. たのしい高階関数 λ  リストを扱う高階関数 map 関数 map 関数 filter 関数 filter 関数 畳込み関数 畳込み関数
  63. 63. たのしい高階関数 λ  リストを扱う高階関数 foldl / foldr 関数のイメージ foldl f 0 [1,2,3,4] foldr f 0 [1,2,3,4] f f f 4 1 f f 3 2 f f 2 3 f 0 1 4 0 関数 f でリストを畳み込んで単一の値を返す。 左からと右からの畳み込み関数がある。
  64. 64. たのしい高階関数 λ   一応やっときます
  65. 65. たのしい高階関数 λ   右も左もないですが + + + + =
  66. 66. たのしい高階関数 λ  リストを扱う高階関数 foldl / foldr 関数の例 > let add x y = x + y > foldl add 0 [1,2,3,4] 10 > foldr add 0 [1,2,3,4] 10
  67. 67. たのしい高階関数 λ  リストを扱う高階関数 foldl / foldr 関数の例 > let add x y = x + y > foldl add 0 [1,2,3,4] = add(add(add(add(0, 1), 2), 3), 4) = add(add(add(1, 2), 3), 4) = add(add(3, 3), 4) = add(6, 4) =10 > foldr add 0 [1,2,3,4] 10
  68. 68. たのしい高階関数 λ  リストを扱う高階関数 foldl / foldr 関数の例 > let add x y = x + y > foldl add 0 [1,2,3,4] 10 > foldr add 0 [1,2,3,4] = add(1, add(2, add(3, add(4, 0)))) = add(1, add(2, add(3, 4))) = add(1, add(2, 7)) = add(1, 9) = 10
  69. 69. たのしい高階関数 λ  リストを扱う高階関数 foldr 関数の実装 foldr :: (a -> b -> b) -> b -> [a] -> b foldr k z = go where go [] = z go (y:ys) = y `k` go ys
  70. 70. たのしい高階関数 λ  リストを扱う高階関数 foldr 関数の実装 foldr :: (a -> b -> b) -> b -> [a] -> b foldr k z = go where go [] = z go (y:ys) = y `k` go ys foldr k z [] = z foldr k z (y:ys) = k y (foldr k z ys)
  71. 71. たのしい高階関数 λ  リストを扱う高階関数 foldl 関数の実装 foldl :: (a -> b -> a) -> a -> [b] -> a foldl f z0 xs0 = lgo z0 xs0 where lgo z [] = z lgo z (x:xs) = lgo (f z x) xs
  72. 72. たのしい高階関数 λ  リストを扱う高階関数 foldl 関数の実装 foldl :: (a -> b -> a) -> a -> [b] -> a foldl f z0 xs0 = lgo z0 xs0 where lgo z [] = z lgo z (x:xs) = lgo (f z x) xs foldl f z [] = z foldl f z (x:xs) = foldl f (f z x) xs
  73. 73. たのしい高階関数 λ  リストを扱う高階関数 foldLeft 関数の実装 (Scala) def foldLeft[B](z: B)(f: (B, A) => B): B = { var acc = z var these = this while (!these.isEmpty) { acc = f(acc, these.head) these = these.tail } acc }
  74. 74. たのしい高階関数 λ  リストを扱う高階関数 foldRight 関数の実装 (Scala) def foldRight[B](z: B)(f: (A, B) => B): B = if (this.isEmpty) z else f(head, tail.foldRight(z)(f))
  75. 75. たのしい高階関数 λ  リストを扱う高階関数 Scala の foldRight 関数の注意点 scala> (1 to 10000).toList.foldLeft(0)(_ + _) res0: Int = 50005000 scala> (1 to 10000).toList.foldRight(0)(_ + _) java.lang.StackOverflowError
  76. 76. たのしい高階関数 λ  リストを扱う高階関数 Range の場合は大丈夫 scala> (1 to 10000).foldLeft(0)(_ + _) res0: Int = 50005000 scala> (1 to 10000).foldRight(0)(_ + _) res1: Int = 50005000
  77. 77. たのしい高階関数 λ  リストを扱う高階関数 Range の foldRight 関数の実装 def foldRight[B](z: B)(op: (A, B) => B): B = reversed.foldLeft(z)((x, y) => op(y, x)) まさかの reversed ! Reversed は List 型を返すので、 List の foldLeft が使われる
  78. 78. たのしい高階関数 λ  Agenda 高階関数ってなに? 高階関数を学ぶメリット リストを扱う高階関数 まとめ
  79. 79. たのしい高階関数 λ   ・高階関数は関数を引数に渡せるので、処理の再利用が  行いやすい(型推論やラムダ式などの言語支援が重要) ・パターンを覚えると、他の関数型言語でも応用が利く ・リスト処理の高階関数のように、便利で強力な関数が  最初から用意されている
  80. 80. ご清聴ありがとうございました!!

×