64
関数型プログラ ミングの世界 Welcome to the world of the functional programming 村田 賢太 Kenta Murata 2011.06.11 #osc11do 1 Monday, June 13, 2011

関数型プログラミングの世界

Embed Size (px)

DESCRIPTION

関数型プログラミングで重要となる高階関数と遅延評価について紹介。時間の関係で、遅延評価については Why Functional Programming Matters とその関連 URL の紹介しかしていない。

Citation preview

Page 1: 関数型プログラミングの世界

関数型プログラミングの世界Welcome to the world of the functional programming

村田 賢太Kenta Murata 2011.06.11 #osc11do

1Monday, June 13, 2011

Page 2: 関数型プログラミングの世界

自己紹介

2Monday, June 13, 2011

Page 3: 関数型プログラミングの世界

http://www.flickr.com/photos/koichiroo/5244581973/

村田賢太mrkn

高専カンファレンス副代表

Ruby コミッタRuby 札幌

3Monday, June 13, 2011

Page 4: 関数型プログラミングの世界

2010年3月1日月曜日 4Monday, June 13, 2011

Page 5: 関数型プログラミングの世界

関数型プログラミングの世界Welcome to the world of the functional programming

村田 賢太Kenta Murata 2011.06.11 #osc11do

5Monday, June 13, 2011

Page 6: 関数型プログラミングの世界

Functional Programming

関数型プログラミング

6Monday, June 13, 2011

Page 7: 関数型プログラミングの世界

Imperative Programming

Procedural Programming

命令型プログラミング手続き型プログラミング

7Monday, June 13, 2011

Page 8: 関数型プログラミングの世界

機械語Fortran

BasicCobolAlgol

CC++JavaLISP

8Monday, June 13, 2011

Page 9: 関数型プログラミングの世界

状態を書き換えることで計算を進めていく

9Monday, June 13, 2011

Page 10: 関数型プログラミングの世界

Functional Programming

関数型プログラミング

10Monday, June 13, 2011

Page 11: 関数型プログラミングの世界

High-order Functions

Lazy Evaluation

高階関数遅延 (怠惰) 評価

11Monday, June 13, 2011

Page 12: 関数型プログラミングの世界

http://www.flickr.com/photos/stevendepolo/5597111652

Functionsas Building Blocks

for constructing programs12Monday, June 13, 2011

Page 13: 関数型プログラミングの世界

http://www.flickr.com/photos/pseudoego/5417919481

Functions as Gluefor bonding functions

13Monday, June 13, 2011

Page 14: 関数型プログラミングの世界

http://www.flickr.com/photos/32712959@N07/3222623206

A lot of programming languages

available forfunctional programming

14Monday, June 13, 2011

Page 15: 関数型プログラミングの世界

C でもVB でもPHP でも

15Monday, June 13, 2011

Page 16: 関数型プログラミングの世界

関数型言語を使う理由はプログラムを関数型のやり方で自然に記述するため

16Monday, June 13, 2011

Page 17: 関数型プログラミングの世界

自然だから脳を邪魔しない

17Monday, June 13, 2011

Page 18: 関数型プログラミングの世界

High-order Functions

高階関数

18Monday, June 13, 2011

Page 19: 関数型プログラミングの世界

例リスト処理

19Monday, June 13, 2011

Page 20: 関数型プログラミングの世界

リスト処理を最も得意とする言語は LISP ではなく関数型言語である

20Monday, June 13, 2011

Page 21: 関数型プログラミングの世界

Haskell での線形リストは [ と ] で囲み、要素をカンマで区切って並べる。

e.g. [] [1, 2, 3]

この表記は糖衣構文であり、内部ではコロン演算子 (:) で要素をひとつずつ結合させ、末尾に空リストを置く表記に変換されている。

e.g. [1] => 1 : [] [1, 2, 3] => 1 : 2 : 3 : []

21Monday, June 13, 2011

Page 22: 関数型プログラミングの世界

リストを構築するコロン演算 (:) は、LISP では cons 関数に対応する。

cons をあえて Haskell で関数として定義すると以下のようになる。

cons :: a -> [a] -> [a] -- 型宣言cons x [] = [x] -- 関数の本体cons x1 (x2:xs) = x1 : (cons x2 xs)

22Monday, June 13, 2011

Page 23: 関数型プログラミングの世界

cons :: a -> [a] -> [a] -- 型宣言

cons x [] = [x] -- 関数の本体cons x1 (x2:xs) = x1 : (cons x2 xs)

// 型宣言を C++ で書くとtemplate <typename a>std::list<a>cons(a const& x, std::list<a> const& xs);

引数 返り値

第1引数↓

第2引数↓

23Monday, June 13, 2011

Page 24: 関数型プログラミングの世界

cons :: a -> [a] -> [a] -- 型宣言

cons x [] = [x] -- 関数の本体cons x1 (x2:xs) = x1 : (cons x2 xs)

e.g. cons 0 [1,2,3,4] => x1 は 0, x2 は 1, xs は [2,3,4]

引数 返り値

第1引数↓

第2引数↓

リストパターン: リスト型の値を分解し 各変数へ束縛する

24Monday, June 13, 2011

Page 25: 関数型プログラミングの世界

引数で与えられた整数 (Int) のリストについて、全要素の総和を求める関数 sum は以下のようになる。

sum :: [Int] -> Intsum [] = 0sum (n:ns) = n + (sum ns)

25Monday, June 13, 2011

Page 26: 関数型プログラミングの世界

cons と sum を比較してみよう。

cons :: a -> [a] -> [a]cons x [] = [x]cons x1 (x2:xs) = x1 : (cons x2 xs)

sum :: [Int] -> Intsum [] = 0sum (n:ns) = n + (sum ns)

共通のパターンが見えませんか?

26Monday, June 13, 2011

Page 27: 関数型プログラミングの世界

cons x [] = [x]sum [] = 0

cons x1 (x2:xs) = x1 : (cons x2 xs)sum (n :ns) = n + (sum ns)

似てるでしょ?

27Monday, June 13, 2011

Page 28: 関数型プログラミングの世界

引数で与えられた整数 (Int) のリストについて、全要素の総積を求める関数 product は以下のようになる。

product :: [Int] -> Intproduct [] = 1product (n:ns) = n * product ns

28Monday, June 13, 2011

Page 29: 関数型プログラミングの世界

cons x [] = [x]sum [] = 0product [] = 1

cons x1 (x2:xs) = x1 : (cons x2 xs)sum (n :ns) = n + (sum ns)product (n :ns) = n * (product ns)

似てるでしょ?

29Monday, June 13, 2011

Page 30: 関数型プログラミングの世界

引数で与えられた真偽値 (Bool) のリストについて、全要素の論理積を求める関数 allTrue は以下のようになる。

allTrue :: [Bool] -> BoolallTrue [] = TrueallTrue (b:bs) = b && allTrue ns

30Monday, June 13, 2011

Page 31: 関数型プログラミングの世界

引数で与えられた真偽値 (Bool) のリストについて、全要素の論理和を求める関数 anyTrue は以下のようになる。

anyTrue :: [Bool] -> BoolanyTrue [] = FalseanyTrue (b:bs) = b || anyTrue ns

31Monday, June 13, 2011

Page 32: 関数型プログラミングの世界

cons x [] = [x]sum [] = 0product [] = 1allTrue [] = TrueanyTrue [] = False

cons x1 (x2:xs) = x1 : (cons x2 xs)sum (n :ns) = n + (sum ns)product (n :ns) = n * (product ns)allTrue (b :bs) = b && (allTrue bs)anyTrue (b :bs) = b || (anyTrue bs)

似てるでしょ?

32Monday, June 13, 2011

Page 33: 関数型プログラミングの世界

cons x [] = [x]sum [] = 0product [] = 1allTrue [] = TrueanyTrue [] = False

cons x1 (x2:xs) = x1 : (cons x2 xs)sum (n :ns) = n + (sum ns)product (n :ns) = n * (product ns)allTrue (b :bs) = b && (allTrue bs)anyTrue (b :bs) = b || (anyTrue bs)

似てるでしょ?

各関数に固有の値は以下の3つ 関数名 空リストに対する値 演算子

32Monday, June 13, 2011

Page 34: 関数型プログラミングの世界

関数固有の値をパラメータとする関数を抽出

reduce :: (a -> [a] -> a) -> a -> [a] -> areduce f x0 [] = x0reduce f x0 (x1:xs) = f x1 (reduce f x0 xs)

この関数を使うと以下のように書き換えられる。

sum = reduce (+) 0product = reduce (*) 1allTrue = reduce (&&) TrueanyTrue = reduce (||) False

33Monday, June 13, 2011

Page 35: 関数型プログラミングの世界

関数固有の値をパラメータとする関数を抽出

reduce :: (a -> [a] -> a) -> a -> [a] -> areduce f x0 [] = x0reduce f x0 (x1:xs) = f x1 (reduce f x0 xs)

この関数を使うと以下のように書き換えられる。

sum = reduce (+) 0product = reduce (*) 1allTrue = reduce (&&) TrueanyTrue = reduce (||) False

33Monday, June 13, 2011

Page 36: 関数型プログラミングの世界

関数固有の値をパラメータとする関数を抽出

reduce :: (a -> [a] -> a) -> a -> [a] -> areduce f x0 [] = x0reduce f x0 (x1:xs) = f x1 (reduce f x0 xs)

この関数を使うと以下のように書き換えられる。

sum = reduce (+) 0product = reduce (*) 1allTrue = reduce (&&) TrueanyTrue = reduce (||) False

引数が足りない → 部分適用

33Monday, June 13, 2011

Page 37: 関数型プログラミングの世界

関数固有の値をパラメータとする関数を抽出

reduce :: (a -> [a] -> a) -> a -> [a] -> areduce f x0 [] = x0reduce f x0 (x1:xs) = f x1 (reduce f x0 xs)

この関数を使うと以下のように書き換えられる。

sum = reduce (+) 0product = reduce (*) 1allTrue = reduce (&&) TrueanyTrue = reduce (||) False

引数が足りない → 部分適用足りない引数を受け取る関数になる (カリー化)

33Monday, June 13, 2011

Page 38: 関数型プログラミングの世界

cons と reduce を使うとリストの結合を作れる

append :: [a] -> [a] -> [a]append xs ys = reduce (:) ys xs

展開すれば分かる

append [1,2] [3,4]-> reduce (:) [3,4] [1,2]-> reduce (:) [3,4] (1:2:[])-> 1 : (reduce (:) [3,4] (2:[]))-> 1 : 2 : (reduce (:) [3,4] [])-> 1 : 2 : [3,4]-> [1,2,3,4]

34Monday, June 13, 2011

Page 39: 関数型プログラミングの世界

Haskell (関数型言語) はリスト処理を LISP なんかよりも随分と素直に表現できている

35Monday, June 13, 2011

Page 40: 関数型プログラミングの世界

関数が勝手にカリー化される

36Monday, June 13, 2011

Page 41: 関数型プログラミングの世界

高階関数を自然に使える

37Monday, June 13, 2011

Page 42: 関数型プログラミングの世界

http://www.flickr.com/photos/stevendepolo/5597111652

Functionsas Building Blocks

for constructing programs38Monday, June 13, 2011

Page 43: 関数型プログラミングの世界

http://www.flickr.com/photos/pseudoego/5417919481

Functions as Gluefor bonding functions

39Monday, June 13, 2011

Page 44: 関数型プログラミングの世界

非関数型言語でも同じ考え方は流用できる

40Monday, June 13, 2011

Page 45: 関数型プログラミングの世界

-- Haskellreduce (+) 0 [1..10]

// C++int ns[] = {1,2,3,4,5,6,7,8,9,10};std::accumulate(ns, ns + 10, 0, &std::plus<int>);

# Ruby[*1..10].inject(0, :+)

41Monday, June 13, 2011

Page 46: 関数型プログラミングの世界

関数型言語は自然だから脳を邪魔しない

42Monday, June 13, 2011

Page 47: 関数型プログラミングの世界

Lazy Evaluation

遅延 (怠惰) 評価

43Monday, June 13, 2011

Page 48: 関数型プログラミングの世界

関数型プログラミングの真髄

44Monday, June 13, 2011

Page 49: 関数型プログラミングの世界

無限を手玉に取る力

45Monday, June 13, 2011

Page 50: 関数型プログラミングの世界

http://www.sampou.org/haskell/article/whyfp.html46Monday, June 13, 2011

Page 51: 関数型プログラミングの世界

http://www.infoq.com/interviews/john-hughes-fp47Monday, June 13, 2011

Page 52: 関数型プログラミングの世界

http://weblog.raganwald.com/2007/03/why-why-functional-programming-matters.html48Monday, June 13, 2011

Page 53: 関数型プログラミングの世界

language evaluation pureness

Haskell lazy pure

Concurrent Clean lazy pure

OCaml strict impure

F# strict impure

Scheme strict impure

49Monday, June 13, 2011

Page 54: 関数型プログラミングの世界

language evaluation pureness

Haskell lazy pure

Concurrent Clean lazy pure

OCaml strict impure

F# strict impure

Scheme strict impure

50Monday, June 13, 2011

Page 55: 関数型プログラミングの世界

おさらい

51Monday, June 13, 2011

Page 56: 関数型プログラミングの世界

2010年3月1日月曜日 52Monday, June 13, 2011

Page 57: 関数型プログラミングの世界

Functional Programming

関数型プログラミング

53Monday, June 13, 2011

Page 58: 関数型プログラミングの世界

http://www.flickr.com/photos/32712959@N07/3222623206

A lot of programming languages

available forfunctional programming

54Monday, June 13, 2011

Page 59: 関数型プログラミングの世界

関数型言語を使う理由はプログラムを関数型のやり方で自然に記述するため

55Monday, June 13, 2011

Page 60: 関数型プログラミングの世界

High-order Functions

高階関数

56Monday, June 13, 2011

Page 61: 関数型プログラミングの世界

http://www.flickr.com/photos/stevendepolo/5597111652

Functionsas Building Blocks

for constructing programs57Monday, June 13, 2011

Page 62: 関数型プログラミングの世界

http://www.flickr.com/photos/pseudoego/5417919481

Functions as Gluefor bonding functions

58Monday, June 13, 2011

Page 63: 関数型プログラミングの世界

Lazy Evaluation

遅延 (怠惰) 評価

59Monday, June 13, 2011

Page 64: 関数型プログラミングの世界

無限を手玉に取る力

60Monday, June 13, 2011