SlideShare a Scribd company logo
1 of 20
Download to read offline
静岡Developers勉強会
第11回Programming Haskell読書会
第12章 遅延評価
tw:ishisaka
遅延評価
 必要となるまで関数の引数を評価しないこと
手続型言語と純粋関数型言語
 手続型(命令型)言語では式の評価順序が変わると計算
結果が変わってしまう。
 Haskellでは状態を持たないので式の評価順序が変わっ
ても結果は変化しない。
 それでも評価の順番は実用上の重大な問題
評価戦略
 一つ以上の引数へ適用されている関数を含み、その適
用を実行すると簡約可能な式は、簡約可能式(redex)と
呼ばれる。
 式を簡約すると通常は大きさ小さくなるが、いつでも小さ
くなるとは限らない。
multi :: (Int, Int) -> Int
multi(x, y) = x * y
multi (1 + 2, 2 + 3) を簡約すると?
multi (3, 2+3), multi (1 + 2, 5), (1 + 2) * (2 + 3)に簡約される
評価戦略(最内簡約)
 簡単にまとめると引数を先に評価していく
 手続型に慣れていると自然な流れ
 式の内側から、それ以上内側がなければ左から簡約していく
muti (1 + 2, 2 + 3) [ 1+2と2+3はこれ以上簡約できない]
= multi (3, 2 + 3)
= multi (3, 5)
= 3 * 5
= 15
 このように最内の式を評価して関数に引数を渡すことを「値渡
し」と呼ぶ
評価戦略(最外簡約)
 外側の関数から簡約する
 Haskellの評価方法はこちら
multi(1 +2, 2 + 3)
= (1+2) * (2+3) [関数が適用される]
= 3 * (2+3)
= 3 * 5
= 15
 この場合は引数は(まだ評価されていないので)「名前」として
渡されていると表現する(名前渡し)
評価戦略(正格)
 Haskellの組み込み関数や*,+のような演算子は引数二
つが評価されて数値にならないと適応できない。
 このような性質を持つ関数は「正格」であると呼ばれる。
λ式
 Haskellではλ式の中の簡約可能式を選択ことは禁止
 λ式の中はブラックボックスで触っちゃダメ
 許されるλ式への操作は、引数の適用だけ
 適用して,中身を取り出してはじめて中の簡約式に触れ
る
 λx->1+2
 1+2は簡約可能であるが、完全に評価済みとみなす
停止性
inf = 1 + inf
この式はずーーーっと再帰を繰り返すので終わらない。
fst(0, inf)
 fstは組の最初の要素を返す関数
 通常の手続型言語だと最内簡約なので先にinfの評価を始
めるので永久に式は終わらない
 Haskellは名前渡しなので、最初にfst関数が適応され、最初
の要素である0が返される。
 つまり結果としてinfの評価はしないので、式が永久に終わ
らないという事はない。
 遅延評価なら理論的に終了できるなら終了できる
遅延評価
 名前渡しでは引数がコピーされてから評価されることが
あるので、同じ引数が何度も評価されうる。
名前渡しの例:
square (1 + 2)
= (1+2) * (1+2)
= 3 * (1+2)
= 3 * 3
=9
 引数が複数回評価され、値渡しより名前渡しのほうが簡約の
回数が増える場合がある。
遅延評価
 名前渡しの効率の悪さは共有される式をポインタで刺す
という方法で解決できる
 square(1+2)という式であれば、1+2の結果はポインタで共有で
きる。したがって実際にはこの場合式の簡約を1回減らすこと
ができる。
 グラフ簡約
 ポインタによる共有を用いた名前渡しは「遅延評価」と呼
ばれる
 Haskellのとる評価戦略はこの遅延評価である。
無限のデータ構造
 遅延評価のおかげで無限の構造を持つデータが扱える
 onesのような無限リストは潜在的無限リストであって、遅
延評価であればコンテキストが必要とされる部分だけが
評価される。
head ones
= head (1:ones)
= 1 <遅延評価であればここで処理が終わる>
部品プログラミング
 遅延評価は計算の際にデータと制御を切り離すことが可
能。
 データは制御が要求する回数だけ評価され、二つの部品は
交互に簡約を実行する。
 Modularity(部品化)という特性を得られる。
 素数での例:
*Main> take 11 primes
[2,3,5,7,11,13,17,19,23,29,31]
 素数のリストを有限の上限という制約から解放し部品化している
部品プログラミング
遅延評価はループの本体から
終了条件を切り離す。
これは強力な部品化の手法である。
 ジョン・フューズ、「なぜ関数プログラミングは重要か」
 http://www.sampou.org/haskell/article/whyfp.html
部品化
 椅子を作る
 手続型
 丸太から切り出す
 遅延評価
 底+背+足+のり
部品化と遅延評価
仕様:
replicate 5 ’*’ → "*****"
手続型でのLoop:
replicate (n, x) {
var ret = "";
for (var i = 0; i < n; i++)
ret = push(x,ret);
return ret;
}
遅延評価による部品化:
repeat ’*’
→ [’*’,’*’,’*’,’*’,’*’, …]
take 5 [’*’,’*’,’*’,’*’,’*’, …]
→ [’*’,’*’,’*’,’*’,’*’]
→ "*****"
replicate n c = take n (repeat c)
正格適用
 いつでも遅延評価が良いとは限らない
 正格評価が適していることもある。
 $! :正格評価の演算子
 正格評価は処理効率を上げる場合もあるが、正格の利
用は専門的な話題であり、遅延評価の振る舞いに対し
て深い考察を必要とする。
まとめ
 遅延評価はHaskellのような関数型言語の特徴です
 遅延評価により、ソフトウェアの部品化を獲得できます。
 遅延評価がいつも有効ではありませんが、遅延評価以
外の方法をとる場合にはその必要性に対する考察が必
要です。
おまけ
 関数型言語以外で遅延評価は不可能か?
 基本的にクロージャを構文に持つ言語であれば原則可能な
はず。
 C#, Ruby, ...
 C#: http://msdn.microsoft.com/ja-jp/ff730144.aspx
 C#はまぁ確実に関数型言語への道を。。。
 開発責任者のA.ヘルスバーグが2006年に日本で明言。
 Q. C#の今後の方向性は関数型に向かうのか?
 A.Yes.

More Related Content

Viewers also liked

Git for windows情報アップデート 2014年10月5日
Git for windows情報アップデート 2014年10月5日Git for windows情報アップデート 2014年10月5日
Git for windows情報アップデート 2014年10月5日
Tadahiro Ishisaka
 
ビジネス向けアプリケーションにこそ進めるMicro orm
ビジネス向けアプリケーションにこそ進めるMicro ormビジネス向けアプリケーションにこそ進めるMicro orm
ビジネス向けアプリケーションにこそ進めるMicro orm
Tadahiro Ishisaka
 

Viewers also liked (20)

Shizudev git hub宿題
Shizudev git hub宿題Shizudev git hub宿題
Shizudev git hub宿題
 
Git for windows情報アップデート 2014年10月5日
Git for windows情報アップデート 2014年10月5日Git for windows情報アップデート 2014年10月5日
Git for windows情報アップデート 2014年10月5日
 
Windows Windows上に作るチーム開発環境
Windows Windows上に作るチーム開発環境Windows Windows上に作るチーム開発環境
Windows Windows上に作るチーム開発環境
 
Arch TCP/IP Introduction
Arch TCP/IP IntroductionArch TCP/IP Introduction
Arch TCP/IP Introduction
 
Esentのススメ
EsentのススメEsentのススメ
Esentのススメ
 
Web matrix2とvisual studio
Web matrix2とvisual studioWeb matrix2とvisual studio
Web matrix2とvisual studio
 
Sysprep
SysprepSysprep
Sysprep
 
Diseño de letrinas #2
Diseño de letrinas #2Diseño de letrinas #2
Diseño de letrinas #2
 
Netduino
NetduinoNetduino
Netduino
 
Visual studio 2015 update1 ctpとcsi
Visual studio 2015 update1 ctpとcsiVisual studio 2015 update1 ctpとcsi
Visual studio 2015 update1 ctpとcsi
 
ビジネス向けアプリケーションにこそ進めるMicro orm
ビジネス向けアプリケーションにこそ進めるMicro ormビジネス向けアプリケーションにこそ進めるMicro orm
ビジネス向けアプリケーションにこそ進めるMicro orm
 
私はこの本でネットワークを学んだ
私はこの本でネットワークを学んだ私はこの本でネットワークを学んだ
私はこの本でネットワークを学んだ
 
Visual studioとそのライバル
Visual studioとそのライバルVisual studioとそのライバル
Visual studioとそのライバル
 
Build insider offline session チームでのgit
Build insider offline session チームでのgitBuild insider offline session チームでのgit
Build insider offline session チームでのgit
 
開発から見たWindowsの国際化機能
開発から見たWindowsの国際化機能開発から見たWindowsの国際化機能
開発から見たWindowsの国際化機能
 
Ossで作成するチーム開発環境
Ossで作成するチーム開発環境Ossで作成するチーム開発環境
Ossで作成するチーム開発環境
 
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門関数型・オブジェクト指向宗教戦争に疲れたなたに送るGo言語入門
関数型・オブジェクト指向 宗教戦争に疲れたなたに送るGo言語入門
 
Windows環境でのgitまとめ(2016.8)
Windows環境でのgitまとめ(2016.8)Windows環境でのgitまとめ(2016.8)
Windows環境でのgitまとめ(2016.8)
 
Windows環境でのgitまとめ(2016.1)
Windows環境でのgitまとめ(2016.1)Windows環境でのgitまとめ(2016.1)
Windows環境でのgitまとめ(2016.1)
 
【14-D-4】デベロッパー戦国時代!ストーリーをつなぐ開発環境と3つの秘訣
【14-D-4】デベロッパー戦国時代!ストーリーをつなぐ開発環境と3つの秘訣【14-D-4】デベロッパー戦国時代!ストーリーをつなぐ開発環境と3つの秘訣
【14-D-4】デベロッパー戦国時代!ストーリーをつなぐ開発環境と3つの秘訣
 

Similar to 静岡Developers勉強会 第11回 第12章 遅延評価

プログラミングHaskell(第1章)
プログラミングHaskell(第1章)プログラミングHaskell(第1章)
プログラミングHaskell(第1章)
yaju88
 
融合変換による最適化の理論的基盤と正当性 (2006-06-27)
融合変換による最適化の理論的基盤と正当性 (2006-06-27)融合変換による最適化の理論的基盤と正当性 (2006-06-27)
融合変換による最適化の理論的基盤と正当性 (2006-06-27)
Masahiro Sakai
 
「Lispインタープリター」勉強会 2014.12.04
「Lispインタープリター」勉強会 2014.12.04「Lispインタープリター」勉強会 2014.12.04
「Lispインタープリター」勉強会 2014.12.04
Minoru Chikamune
 

Similar to 静岡Developers勉強会 第11回 第12章 遅延評価 (13)

プログラミングHaskell(第1章)
プログラミングHaskell(第1章)プログラミングHaskell(第1章)
プログラミングHaskell(第1章)
 
融合変換による最適化の理論的基盤と正当性 (2006-06-27)
融合変換による最適化の理論的基盤と正当性 (2006-06-27)融合変換による最適化の理論的基盤と正当性 (2006-06-27)
融合変換による最適化の理論的基盤と正当性 (2006-06-27)
 
関数プログラミング入門
関数プログラミング入門関数プログラミング入門
関数プログラミング入門
 
[Basic 12] 関数型言語 / 型理論
[Basic 12] 関数型言語 / 型理論[Basic 12] 関数型言語 / 型理論
[Basic 12] 関数型言語 / 型理論
 
Java8 lambdas chapter1_2
Java8 lambdas chapter1_2Java8 lambdas chapter1_2
Java8 lambdas chapter1_2
 
[DL輪読会]大規模分散強化学習の難しい問題設定への適用
[DL輪読会]大規模分散強化学習の難しい問題設定への適用[DL輪読会]大規模分散強化学習の難しい問題設定への適用
[DL輪読会]大規模分散強化学習の難しい問題設定への適用
 
TypeScript & 関数型講座 第3回 関数型入門
TypeScript & 関数型講座 第3回 関数型入門TypeScript & 関数型講座 第3回 関数型入門
TypeScript & 関数型講座 第3回 関数型入門
 
「Lispインタープリター」勉強会 2014.12.04
「Lispインタープリター」勉強会 2014.12.04「Lispインタープリター」勉強会 2014.12.04
「Lispインタープリター」勉強会 2014.12.04
 
Tdd
TddTdd
Tdd
 
並行プログラミング with Haskell
並行プログラミング with Haskell並行プログラミング with Haskell
並行プログラミング with Haskell
 
L-R
L-RL-R
L-R
 
Haskell勉強会 in ie
Haskell勉強会 in ieHaskell勉強会 in ie
Haskell勉強会 in ie
 
Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術
 

静岡Developers勉強会 第11回 第12章 遅延評価