たのしい高階関数
DESCRIPTION
第2回関数型勉強会 in 大阪 で使った資料です。TRANSCRIPT
λλfunctionalfunctional
presented by presented by @s_kozake@s_kozake
map / filter / foldl / foldrmap / filter / foldl / foldr
in in
λλたのしい高階関数たのしい高階関数
発表をする資料をつくる資料をあきらめる
▲
こわくないよこわくないよ
たのしい高階関数 たのしい高階関数 λλ
目的目的本勉強会の趣旨
本セッションは高階関数入門です関数型言語の視野を拡げ、たのしく使っていくことを目的としております。
つまりですねつまりですね
たのしい高階関数 たのしい高階関数 λλ
目的目的本勉強会の趣旨
本セッションは高階関数入門です関数型言語の視野を拡げ、たのしく使っていくことを目的としております。
大事なことなので大事なことなので2回いいました2回いいました
たのしい高階関数 たのしい高階関数 λλ
注意事項注意事項
たのしい高階関数 たのしい高階関数 λλ
関数型言語は怖いイメージがあるみたいですが
たのしい高階関数 たのしい高階関数 λλ
当セッションはイージーモードです。当セッションはイージーモードです。
たのしい高階関数 たのしい高階関数 λλ
ダメ。ゼッタイ。ダメ。ゼッタイ。
モナド / ファンクタ / 遅延評価 / 圏論 / 論証
「みんなやってる」なんて理由にならない
このようなこのような悲劇悲劇を繰り返さないためにもねを繰り返さないためにもね
プログラマたちは ぜんめつしました。
たのしくたのしく学びましょう~学びましょう~
たのしい高階関数 たのしい高階関数 λλ
自己紹介自己紹介
Java Scala
★★☆
☆☆☆
Haskell ☆☆☆
アストルティア
Twitter@s_kozake
そろそろ Scala で仕事したいです。
たのしい高階関数 たのしい高階関数 λλ
高階関数ってなに?
高階関数を学ぶメリット
リストを扱う高階関数
まとめ
AgendaAgenda
たのしい高階関数 たのしい高階関数 λλ
高階関数ってなに?
高階関数を学ぶメリット
リストを扱う高階関数
まとめ
AgendaAgenda
たのしい高階関数 たのしい高階関数 λλ
高階関数ってなに?高階関数ってなに?
引数として関数を取ったり、引数として関数を取ったり、返り値として関数を返したりする関数返り値として関数を返したりする関数
関数型言語では、関数型言語では、関数がファーストクラスオブジェクト関数がファーストクラスオブジェクトとして扱える。として扱える。
たのしい高階関数 たのしい高階関数 λλ
高階関数ってなに?高階関数ってなに?
ファーストクラスオブジェクトとはファーストクラスオブジェクトとは
・無名のリテラルとして表現可能・無名のリテラルとして表現可能・変数に格納可能・変数に格納可能・データ構造への組み込みが可能・データ構造への組み込みが可能・プロシージャや関数のパラメータとして渡すことができる・プロシージャや関数のパラメータとして渡すことができる・プロシージャや関数の戻り値として返すことができる・プロシージャや関数の戻り値として返すことができる
たのしい高階関数 たのしい高階関数 λλ
高階関数ってなに?高階関数ってなに?
def twice(f:(Int => Int))(x:Int):Int = f(f(x))def twice(f:(Int => Int))(x:Int):Int = f(f(x))
たのしい高階関数 たのしい高階関数 λλ
def twice(def twice(f:(Int => Int)f:(Int => Int)))(x:Int):Int(x:Int):Int = f(f(x)) = f(f(x))
高階関数ってなに?高階関数ってなに?
関数 関数 twicetwice ははIntInt 型の引数を受け取り型の引数を受け取り IntInt 型の値を返す関数型の値を返す関数 ffを受け取り、を受け取り、IntInt 型の引数を受け取り型の引数を受け取り IntInt 型の値を返す関数型の値を返す関数を返す関数を返す関数
たのしい高階関数 たのしい高階関数 λλ
def twice(f:(Int => Int))(x:Int):Int = f(f(x))def twice(f:(Int => Int))(x:Int):Int = f(f(x))def add1(x:Int) = x + 1def add1(x:Int) = x + 1
> val add2 = twice(add1)(_)> val add2 = twice(add1)(_)add2: Int => Int = <function1>add2: Int => Int = <function1>
> add2(3)> add2(3)res1: Int = 5res1: Int = 5
高階関数ってなに?高階関数ってなに?
たのしい高階関数 たのしい高階関数 λλ
def twice(f:(Int => Int))(x:Int):Int = f(f(x))def twice(f:(Int => Int))(x:Int):Int = f(f(x))def add1(x:Int) = x + 1def add1(x:Int) = x + 1
> val add2 = twice(add1)(_)> val add2 = twice(add1)(_)add2: Int => Int = <function1>add2: Int => Int = <function1>
> add2(3)> add2(3)res1: Int = 5res1: Int = 5
高階関数ってなに?高階関数ってなに?
IntInt 型の引数を受け取り型の引数を受け取りIntInt 型の値を返す関数型の値を返す関数
IntInt 型の引数を受け取り型の引数を受け取りIntInt 型の値を返す関数型の値を返す関数
たのしい高階関数 たのしい高階関数 λλ
高階関数ってなに?高階関数ってなに?
def twice(f:(Int => Int))(x:Int):Int = f(f(x))def twice(f:(Int => Int))(x:Int):Int = f(f(x))def add1(x:Int) = x + 1def add1(x:Int) = x + 1
> val add2 = twice(add1)(_)> val add2 = twice(add1)(_)add2: Int => Int = <function1>add2: Int => Int = <function1>
> add2(3) > add2(3) = twice(add1)(3) = add1(add1(3))= twice(add1)(3) = add1(add1(3))res1: Int = 5res1: Int = 5
たのしい高階関数 たのしい高階関数 λλ
高階関数ってなに?
高階関数を学ぶメリット
リストを扱う高階関数
まとめ
AgendaAgenda
たのしい高階関数 たのしい高階関数 λλ
高階関数を学ぶメリット高階関数を学ぶメリット
処理の再利用の行いやすさ処理の再利用の行いやすさ
パターンとしての高階関数パターンとしての高階関数
たのしい高階関数 たのしい高階関数 λλ
高階関数を学ぶメリット高階関数を学ぶメリット
処理の再利用の行いやすさ処理の再利用の行いやすさ
パターンとしての高階関数パターンとしての高階関数
たのしい高階関数 たのしい高階関数 λλ
高階関数を学ぶメリット高階関数を学ぶメリット
関数関数 aa
個別処理
共通処理
共通処理
例えば、ある関数例えば、ある関数 aaの大部分がの大部分が共通処理で、一部が個別処理の場合共通処理で、一部が個別処理の場合
例例 ) ) ファイルのファイルの Open/CloseOpen/Close トランザクションの トランザクションの Begin/EndBegin/End リトライ処理 リトライ処理 TreeTreeの走査の走査
たのしい高階関数 たのしい高階関数 λλ
高階関数を学ぶメリット高階関数を学ぶメリット
関数関数 a(x)a(x)
if(x == 1) 個別処理 1else 個別処理 2
共通処理
共通処理
●●値渡しによる処理の分岐値渡しによる処理の分岐
・個別処理が増える度に、・個別処理が増える度に、 関数の処理が増大する 関数の処理が増大する
・関数の引数に制御情報を渡している・関数の引数に制御情報を渡している =制御結合 =制御結合
たのしい高階関数 たのしい高階関数 λλ
高階関数を学ぶメリット高階関数を学ぶメリット
メソッドメソッド aa
Call メソッド b
共通処理
共通処理
●●個別処理の抽象化個別処理の抽象化(( template methodtemplate methodパターン)パターン)
・処理毎にクラスが増える・処理毎にクラスが増える
抽象メソッド b
抽象クラス A
たのしい高階関数 たのしい高階関数 λλ
高階関数を学ぶメリット高階関数を学ぶメリット
関数関数 a(f)a(f)
個別処理 f
共通処理
共通処理
●●関数渡しによる処理の再利用関数渡しによる処理の再利用
・個別処理が増えても・個別処理が増えても 関数本体が複雑にならない 関数本体が複雑にならない
・関数を値として扱える・関数を値として扱える =データ結合 =データ結合
たのしい高階関数 たのしい高階関数 λλ
高階関数を学ぶメリット高階関数を学ぶメリット
関数関数 a(f)(x)a(f)(x)
個別処理 f
共通処理
共通処理
個別処理 1個別処理 1
個別処理 2個別処理 2
個別処理 3個別処理 3
+
+
+
関数 a1(x)
関数 a2(x)
関数 a(x)
=
=
=
関数を組み合わせて新しい関数を関数を組み合わせて新しい関数を作るのも容易作るのも容易
ん?ん?
インターフェース渡しインターフェース渡しがあるじゃん!があるじゃん!
たのしい高階関数 たのしい高階関数 λλ
高階関数を学ぶメリット高階関数を学ぶメリット
例えば、例えば、あるリストの値をあるリストの値を 22倍した結果、倍した結果、1010以上のものを抜き出して全部足した値を求める以上のものを抜き出して全部足した値を求める場合。場合。
list.list.mapmap(_ * (_ * 22).).filterfilter(_ >= (_ >= 1010).).reducereduce(_ + _)(_ + _)
foldrfoldr (+) (+) 00 . . filterfilter (>= (>=1010) . ) . mapmap (* (*22) $ list) $ list
たのしい高階関数 たのしい高階関数 λλ
高階関数を学ぶメリット高階関数を学ぶメリット
list.list.mapmap((newnew Func1<Integer, Integer>Func1<Integer, Integer>() {() { publicpublic IntegerInteger applyapply((IntegerInteger a) { a) { returnreturn a * a * 22;};} }).}).filterfilter((newnew Func1<Integer, Boolean>Func1<Integer, Boolean>() {() { publicpublic BooleanBoolean applyapply((IntegerInteger a) { a) { returnreturn a >= a >= 1010;};}
}).}).reducereduce((newnew Func2<Integer, Integer, Integer>Func2<Integer, Integer, Integer>() {() { publicpublic IntegerInteger applyapply((IntegerInteger a, a, IntegerInteger b) { b) { returnreturn a + b; } a + b; } });});
やってられるか~!!やってられるか~!!
たのしい高階関数 たのしい高階関数 λλ
高階関数を学ぶメリット高階関数を学ぶメリット
処理の再利用の行いやすさ処理の再利用の行いやすさ
・高階関数は関数を引数に渡せるので、・高階関数は関数を引数に渡せるので、 処理の再利用が行いやすい 処理の再利用が行いやすい
・但し、型推論、ラムダ式など、手軽に関数を扱える・但し、型推論、ラムダ式など、手軽に関数を扱える 言語サポートが備わっていることが重要 言語サポートが備わっていることが重要
たのしい高階関数 たのしい高階関数 λλ
高階関数を学ぶメリット高階関数を学ぶメリット
処理の再利用の行いやすさ処理の再利用の行いやすさ
パターンとしての高階関数パターンとしての高階関数
たのしい高階関数 たのしい高階関数 λλ
高階関数を学ぶメリット高階関数を学ぶメリット
例えば、リストの全ての要素に関数を写す関数は例えば、リストの全ての要素に関数を写す関数は mapmap
List(List(11,,22,,33).).mapmap(_ * (_ * 22))
mapmap (* (*22) [) [11,,22,,33]]
[1,2,3].[1,2,3].mapmap((functionfunction(a) { (a) { returnreturn a * a * 22 }) })
JavaScript
たのしい高階関数 たのしい高階関数 λλ
高階関数を学ぶメリット高階関数を学ぶメリット
例えば、例えば、 ScalaScalaのの flatMapflatMapはモナドのはモナドの bindbindと分かればと分かれば以下の動作が容易に推測できる。以下の動作が容易に推測できる。
> List(1,2,3).flatMap(x => List(x*2))> List(1,2,3).flatMap(x => List(x*2))res0: List[Int] = List(2, 4, 6)res0: List[Int] = List(2, 4, 6)
> Some(1).flatMap(x => Some(x*2))> Some(1).flatMap(x => Some(x*2))res1: Option[Int] = Some(2)res1: Option[Int] = Some(2)
たのしい高階関数 たのしい高階関数 λλ
高階関数を学ぶメリット高階関数を学ぶメリット
パターンとしての高階関数パターンとしての高階関数
・関数型言語にはパターンがある。・関数型言語にはパターンがある。
・パターンを覚えれば、他の関数型言語でも応用が利く。・パターンを覚えれば、他の関数型言語でも応用が利く。
たのしい高階関数 たのしい高階関数 λλ
高階関数ってなに?
高階関数を学ぶメリット
リストを扱う高階関数
まとめ
AgendaAgenda
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
map関数map関数
filter関数filter関数
畳込み関数畳込み関数
・神は言われた。「リストあれ」・神は言われた。「リストあれ」
・リストと関数型言語は関連が深い・リストと関数型言語は関連が深い
・・ JavaJavaやってて「あれ欲しい」はやってて「あれ欲しい」は たいていリストの高階関数 たいていリストの高階関数
たのしい高階関数 たのしい高階関数 λλ
リストのおさらいリストのおさらい
0 :: 1 :: 2 :: 3 :: Nil0 :: 1 :: 2 :: 3 :: Nil
1 2 3
[]
0
ヘッダヘッダ テイルテイル ラストラスト NilNil
0 : 1 : 2 : 3 : []0 : 1 : 2 : 3 : []
たのしい高階関数 たのしい高階関数 λλ
リストのおさらいリストのおさらい
つまりですねつまりですね
たのしい高階関数 たのしい高階関数 λλ
リストのおさらいリストのおさらい
こんなイメージこんなイメージ
ヘッダヘッダ テイルテイルラストラスト NilNil
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
map関数map関数
filter関数filter関数
畳込み関数畳込み関数
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
mapmap関数のイメージ関数のイメージ
[1,2,3,4[1,2,3,4・・・・ ,n] ,n]
関数関数 ffをリストに写す(をリストに写す( map overmap over))
[f(1), f(2), f(3), f(4)[f(1), f(2), f(3), f(4)・・・・ ,f(n)],f(n)]
map fmap f
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
let let ベホマラー ベホマラー = map = map ベホイミベホイミ
こういう風に使いますこういう風に使います
let let ルカナン ルカナン = map = map ルカニルカニ
let let スクルト スクルト = map = map スカラスカラ
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
mapmap関数の例関数の例
> map (\x -> x * 2) [1,2,3]> map (\x -> x * 2) [1,2,3][2,4,6][2,4,6]
> map (\x -> "hoge" ++ show(x)) [1,2,3]> map (\x -> "hoge" ++ show(x)) [1,2,3]["hoge1","hoge2","hoge3"]["hoge1","hoge2","hoge3"]
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
mapmap関数の実装関数の実装
mapmap :: (a -> b) -> [a] -> [b] :: (a -> b) -> [a] -> [b]mapmap _ [] = [] _ [] = []mapmap f (x:xs) = f x : f (x:xs) = f x : mapmap f xs f xs
ヘッダヘッダ テイルテイル
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
mapmap関数の実装関数の実装
defdef mapmap[[BB, , ThatThat](f: ](f: AA => => BB)) ((implicitimplicit bf: bf: CanBuildFromCanBuildFrom[[ReprRepr, , BB, , ThatThat])]) : : ThatThat = { = { valval b = b = bfbf(repr)(repr) b.b.sizeHintsizeHint(this)(this) forfor (x <- this) b += f(x) (x <- this) b += f(x) b.b.resultresult }}
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
mapmap関数の実装(簡略化)関数の実装(簡略化)
def map[B, That](f: A => B)def map[B, That](f: A => B) (implicit bf: CanBuildFrom[Repr, B, That])(implicit bf: CanBuildFrom[Repr, B, That]) : That = {: That = { val b = bf(repr)val b = bf(repr) b.sizeHint(this)b.sizeHint(this) for (x <- this) b += f(x)for (x <- this) b += f(x) b.resultb.result }}
defdef mapmap[[AA, , BB](f: ](f: AA => => BB): ): ListList[[BB] = {] = { valval b = b = newnew ListBufferListBuffer[[BB]()]() b.b.sizeHintsizeHint(this)(this) forfor (x <- this) buff += f(x) (x <- this) buff += f(x) b.b.resultresult}}
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
map関数map関数
filter関数filter関数
畳込み関数畳込み関数
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
filterfilter関数のイメージ関数のイメージ
[1,2,3,4[1,2,3,4・・・・ ,n] ,n]
関数関数 ffで要素を篩いに掛けるで要素を篩いに掛ける
filter (x => x < 4) filter (x => x < 4)
[1,2,3] [1,2,3]
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
こういう時に使います こういう時に使います ゲームしばり無視していますが。。ゲームしばり無視していますが。。
let let レベルレベル 55 デス デス = filter (not . is= filter (not . isレベルレベル 5)5)
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
filterfilter関数の例関数の例
> filter (\x -> not(x `mod` 5 == 0)) [3,4,5,10,12]> filter (\x -> not(x `mod` 5 == 0)) [3,4,5,10,12][3,4,12][3,4,12]
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
filterfilter関数の実装関数の実装
filterfilter :: (a -> Bool) -> [a] -> [a] :: (a -> Bool) -> [a] -> [a]filterfilter _pred [] = [] _pred [] = []filterfilter pred (x:xs) pred (x:xs) | pred x = x : | pred x = x : filterfilter pred xs pred xs | otherwise = | otherwise = filterfilter pred xs pred xs
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
filterfilter関数の実装関数の実装
defdef filterfilter(p: (p: AA => => BooleanBoolean): ): ReprRepr = { = { valval b = b = newBuildernewBuilder forfor (x <- this) (x <- this) ifif (p(x)) b += x (p(x)) b += x b.b.resultresult}}
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
map関数map関数
filter関数filter関数
畳込み関数畳込み関数
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
foldl / foldrfoldl / foldr関数のイメージ関数のイメージ
foldr f 0 [1,2,3,4]foldr f 0 [1,2,3,4]
関数関数 ffでリストを畳み込んで単一の値を返す。でリストを畳み込んで単一の値を返す。左からと右からの畳み込み関数がある。左からと右からの畳み込み関数がある。
foldl f 0 [1,2,3,4] foldl f 0 [1,2,3,4]
ff11 ff
22 ff33 ff
44 00
ffff
ff
22ff00 11
3344
たのしい高階関数 たのしい高階関数 λλ
一応やっときます一応やっときます
たのしい高階関数 たのしい高階関数 λλ
右も左もないですが右も左もないですが
++ ++ ++ ++
==
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
foldl / foldrfoldl / foldr関数の例関数の例
> let add x y = x + y> let add x y = x + y> foldl add 0 [1,2,3,4]> foldl add 0 [1,2,3,4]1010
> foldr add 0 [1,2,3,4]> foldr add 0 [1,2,3,4]1010
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
foldl / foldrfoldl / foldr関数の例関数の例
> let add x y = x + y> let add x y = x + y> foldl add 0 [1,2,3,4]> foldl add 0 [1,2,3,4]= add(add(add(add(0, 1), 2), 3), 4)= add(add(add(add(0, 1), 2), 3), 4)= add(add(add(1, 2), 3), 4)= add(add(add(1, 2), 3), 4)= add(add(3, 3), 4)= add(add(3, 3), 4)= add(6, 4)= add(6, 4)=10=10
> foldr add 0 [1,2,3,4]> foldr add 0 [1,2,3,4]1010
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
foldl / foldrfoldl / foldr関数の例関数の例
> let add x y = x + y> let add x y = x + y> foldl add 0 [1,2,3,4]> foldl add 0 [1,2,3,4]1010
> foldr add 0 [1,2,3,4]> foldr add 0 [1,2,3,4]= add(1, add(2, add(3, add(4, 0))))= add(1, add(2, add(3, add(4, 0))))= add(1, add(2, add(3, 4)))= add(1, add(2, add(3, 4)))= add(1, add(2, 7))= add(1, add(2, 7))= add(1, 9)= add(1, 9)= 10= 10
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
foldrfoldr関数の実装関数の実装
foldrfoldr :: (a -> b -> b) -> b -> [a] -> b :: (a -> b -> b) -> b -> [a] -> bfoldrfoldr k z = go k z = go wherewhere go [] = zgo [] = z go (y:ys) = y `k` go ysgo (y:ys) = y `k` go ys
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
foldrfoldr関数の実装関数の実装
foldrfoldr :: (a -> b -> b) -> b -> [a] -> b :: (a -> b -> b) -> b -> [a] -> bfoldrfoldr k z = go k z = go wherewhere go [] = zgo [] = z go (y:ys) = y `k` go ysgo (y:ys) = y `k` go ys
foldrfoldr k z [] = z k z [] = zfoldrfoldr k z (y:ys) = k y ( k z (y:ys) = k y (foldrfoldr k z ys) k z ys)
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
foldlfoldl関数の実装関数の実装
foldlfoldl :: (a -> b -> a) -> a -> [b] -> a :: (a -> b -> a) -> a -> [b] -> afoldlfoldl f z0 xs0 = lgo z0 xs0 f z0 xs0 = lgo z0 xs0 wherewhere lgo z [] = zlgo z [] = z lgo z (x:xs) = lgo (f z x) xslgo z (x:xs) = lgo (f z x) xs
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
foldlfoldl関数の実装関数の実装
foldlfoldl :: (a -> b -> a) -> a -> [b] -> a :: (a -> b -> a) -> a -> [b] -> afoldlfoldl f z0 xs0 = lgo z0 xs0 f z0 xs0 = lgo z0 xs0 wherewhere lgo z [] = zlgo z [] = z lgo z (x:xs) = lgo (f z x) xslgo z (x:xs) = lgo (f z x) xs
foldlfoldl f z [] = z f z [] = zfoldlfoldl f z (x:xs) = f z (x:xs) = foldlfoldl f (f z x) xs f (f z x) xs
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
foldLeftfoldLeft関数の実装関数の実装 (Scala)(Scala)
defdef foldLeftfoldLeft[[BB](z: ](z: BB)(f: ()(f: (BB, , AA) => ) => BB): ): BB = { = { varvar acc = z acc = z varvar these = this these = this whilewhile (!these. (!these.isEmptyisEmpty) {) { acc = f(acc, these.acc = f(acc, these.headhead)) these = these.these = these.tailtail }} accacc}}
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
foldRightfoldRight関数の実装関数の実装 (Scala)(Scala)
defdef foldRightfoldRight[[BB](z: ](z: BB)(f: ()(f: (AA, , BB) => ) => BB): ): BB = = ifif (this. (this.isEmptyisEmpty) z) z elseelse f(head, tail. f(head, tail.foldRightfoldRight(z)(f))(z)(f))
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
ScalaScalaのの foldRightfoldRight関数の注意点関数の注意点
scala> (1 to 10000).toList.foldLeft(0)(_ + _)scala> (1 to 10000).toList.foldLeft(0)(_ + _)res0: Int = 50005000res0: Int = 50005000
scala> (1 to 10000).toList.foldRight(0)(_ + _)scala> (1 to 10000).toList.foldRight(0)(_ + _)java.lang.StackOverflowErrorjava.lang.StackOverflowError
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
RangeRangeの場合は大丈夫の場合は大丈夫
scala> (1 to 10000).foldLeft(0)(_ + _)scala> (1 to 10000).foldLeft(0)(_ + _)res0: Int = 50005000res0: Int = 50005000
scala> (1 to 10000).foldRight(0)(_ + _)scala> (1 to 10000).foldRight(0)(_ + _)res1: Int = 50005000res1: Int = 50005000
たのしい高階関数 たのしい高階関数 λλ
リストを扱う高階関数リストを扱う高階関数
RangeRangeのの foldRightfoldRight関数の実装関数の実装
defdef foldRightfoldRight[[BB](z: ](z: BB)(op: ()(op: (AA, , BB) => ) => BB): ): BB = = reversedreversed..foldLeftfoldLeft(z)((x, y) => op(y, x))(z)((x, y) => op(y, x))
まさかのまさかの reversedreversed!!
ReversedReversedはは ListList型を返すので、型を返すので、ListListのの foldLeftfoldLeftが使われるが使われる
たのしい高階関数 たのしい高階関数 λλ
高階関数ってなに?
高階関数を学ぶメリット
リストを扱う高階関数
まとめ
AgendaAgenda
たのしい高階関数 たのしい高階関数 λλ
・高階関数は関数を引数に渡せるので、処理の再利用が・高階関数は関数を引数に渡せるので、処理の再利用が 行いやすい(型推論やラムダ式などの言語支援が重要) 行いやすい(型推論やラムダ式などの言語支援が重要)
・パターンを覚えると、他の関数型言語でも応用が利く・パターンを覚えると、他の関数型言語でも応用が利く
・リスト処理の高階関数のように、便利で強力な関数が・リスト処理の高階関数のように、便利で強力な関数が 最初から用意されている 最初から用意されている
ご清聴ありがとうご清聴ありがとうございました!!ございました!!