Upload
kenta-murata
View
10.366
Download
6
Embed Size (px)
DESCRIPTION
関数型プログラミングで重要となる高階関数と遅延評価について紹介。時間の関係で、遅延評価については Why Functional Programming Matters とその関連 URL の紹介しかしていない。
Citation preview
関数型プログラミングの世界Welcome to the world of the functional programming
村田 賢太Kenta Murata 2011.06.11 #osc11do
1Monday, June 13, 2011
自己紹介
2Monday, June 13, 2011
http://www.flickr.com/photos/koichiroo/5244581973/
村田賢太mrkn
高専カンファレンス副代表
Ruby コミッタRuby 札幌
3Monday, June 13, 2011
2010年3月1日月曜日 4Monday, June 13, 2011
関数型プログラミングの世界Welcome to the world of the functional programming
村田 賢太Kenta Murata 2011.06.11 #osc11do
5Monday, June 13, 2011
Functional Programming
関数型プログラミング
6Monday, June 13, 2011
Imperative Programming
Procedural Programming
命令型プログラミング手続き型プログラミング
7Monday, June 13, 2011
機械語Fortran
BasicCobolAlgol
CC++JavaLISP
8Monday, June 13, 2011
状態を書き換えることで計算を進めていく
9Monday, June 13, 2011
Functional Programming
関数型プログラミング
10Monday, June 13, 2011
High-order Functions
Lazy Evaluation
高階関数遅延 (怠惰) 評価
11Monday, June 13, 2011
http://www.flickr.com/photos/stevendepolo/5597111652
Functionsas Building Blocks
for constructing programs12Monday, June 13, 2011
http://www.flickr.com/photos/pseudoego/5417919481
Functions as Gluefor bonding functions
13Monday, June 13, 2011
http://www.flickr.com/photos/32712959@N07/3222623206
A lot of programming languages
available forfunctional programming
14Monday, June 13, 2011
C でもVB でもPHP でも
15Monday, June 13, 2011
関数型言語を使う理由はプログラムを関数型のやり方で自然に記述するため
16Monday, June 13, 2011
自然だから脳を邪魔しない
17Monday, June 13, 2011
High-order Functions
高階関数
18Monday, June 13, 2011
例リスト処理
19Monday, June 13, 2011
リスト処理を最も得意とする言語は LISP ではなく関数型言語である
20Monday, June 13, 2011
Haskell での線形リストは [ と ] で囲み、要素をカンマで区切って並べる。
e.g. [] [1, 2, 3]
この表記は糖衣構文であり、内部ではコロン演算子 (:) で要素をひとつずつ結合させ、末尾に空リストを置く表記に変換されている。
e.g. [1] => 1 : [] [1, 2, 3] => 1 : 2 : 3 : []
21Monday, June 13, 2011
リストを構築するコロン演算 (:) は、LISP では cons 関数に対応する。
cons をあえて Haskell で関数として定義すると以下のようになる。
cons :: a -> [a] -> [a] -- 型宣言cons x [] = [x] -- 関数の本体cons x1 (x2:xs) = x1 : (cons x2 xs)
22Monday, June 13, 2011
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
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
引数で与えられた整数 (Int) のリストについて、全要素の総和を求める関数 sum は以下のようになる。
sum :: [Int] -> Intsum [] = 0sum (n:ns) = n + (sum ns)
25Monday, June 13, 2011
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
cons x [] = [x]sum [] = 0
cons x1 (x2:xs) = x1 : (cons x2 xs)sum (n :ns) = n + (sum ns)
似てるでしょ?
27Monday, June 13, 2011
引数で与えられた整数 (Int) のリストについて、全要素の総積を求める関数 product は以下のようになる。
product :: [Int] -> Intproduct [] = 1product (n:ns) = n * product ns
28Monday, June 13, 2011
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
引数で与えられた真偽値 (Bool) のリストについて、全要素の論理積を求める関数 allTrue は以下のようになる。
allTrue :: [Bool] -> BoolallTrue [] = TrueallTrue (b:bs) = b && allTrue ns
30Monday, June 13, 2011
引数で与えられた真偽値 (Bool) のリストについて、全要素の論理和を求める関数 anyTrue は以下のようになる。
anyTrue :: [Bool] -> BoolanyTrue [] = FalseanyTrue (b:bs) = b || anyTrue ns
31Monday, June 13, 2011
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
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
関数固有の値をパラメータとする関数を抽出
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
関数固有の値をパラメータとする関数を抽出
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
関数固有の値をパラメータとする関数を抽出
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
関数固有の値をパラメータとする関数を抽出
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
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
Haskell (関数型言語) はリスト処理を LISP なんかよりも随分と素直に表現できている
35Monday, June 13, 2011
関数が勝手にカリー化される
36Monday, June 13, 2011
高階関数を自然に使える
37Monday, June 13, 2011
http://www.flickr.com/photos/stevendepolo/5597111652
Functionsas Building Blocks
for constructing programs38Monday, June 13, 2011
http://www.flickr.com/photos/pseudoego/5417919481
Functions as Gluefor bonding functions
39Monday, June 13, 2011
非関数型言語でも同じ考え方は流用できる
40Monday, June 13, 2011
-- 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
関数型言語は自然だから脳を邪魔しない
42Monday, June 13, 2011
Lazy Evaluation
遅延 (怠惰) 評価
43Monday, June 13, 2011
関数型プログラミングの真髄
44Monday, June 13, 2011
無限を手玉に取る力
45Monday, June 13, 2011
http://www.sampou.org/haskell/article/whyfp.html46Monday, June 13, 2011
http://www.infoq.com/interviews/john-hughes-fp47Monday, June 13, 2011
http://weblog.raganwald.com/2007/03/why-why-functional-programming-matters.html48Monday, June 13, 2011
language evaluation pureness
Haskell lazy pure
Concurrent Clean lazy pure
OCaml strict impure
F# strict impure
Scheme strict impure
49Monday, June 13, 2011
language evaluation pureness
Haskell lazy pure
Concurrent Clean lazy pure
OCaml strict impure
F# strict impure
Scheme strict impure
50Monday, June 13, 2011
おさらい
51Monday, June 13, 2011
2010年3月1日月曜日 52Monday, June 13, 2011
Functional Programming
関数型プログラミング
53Monday, June 13, 2011
http://www.flickr.com/photos/32712959@N07/3222623206
A lot of programming languages
available forfunctional programming
54Monday, June 13, 2011
関数型言語を使う理由はプログラムを関数型のやり方で自然に記述するため
55Monday, June 13, 2011
High-order Functions
高階関数
56Monday, June 13, 2011
http://www.flickr.com/photos/stevendepolo/5597111652
Functionsas Building Blocks
for constructing programs57Monday, June 13, 2011
http://www.flickr.com/photos/pseudoego/5417919481
Functions as Gluefor bonding functions
58Monday, June 13, 2011
Lazy Evaluation
遅延 (怠惰) 評価
59Monday, June 13, 2011
無限を手玉に取る力
60Monday, June 13, 2011