F#の基礎(嘘)
bleis-tift
December 7, 2013
自己紹介

id:bleis-tift / @bleis
なごやではたらくゆるふわ.NETer
好きな関数型言語は F#
Microsoft MVP for Visual F#
なんか話せって言われたので・
・
・

過去の基礎勉強会での発表を使い回しても問
題ないよねっ
.NET 基礎での資料ほぼそのまま
.NET と言えば F#(異論は認める
F#の基礎と言えばラムダ計算ですよねー
ということで (型無し) ラムダ...
聞いたことある人は休憩時間です!
ことりちゃんを愛でていればいいと思うよ!
今日やること

ラムダ計算って何?
ラムダ計算で計算してみる
最終的には階乗を計算してみます
ラムダ計算って何?
その前に

関数型言語って何?
関数型言語とは
ある人曰く、
「それぞれの人が色々な特徴か
ら適当なサブセットを選んで関数型と呼ぶ」
ある人曰く、
「永続的データ構造を扱う言
語だ」
ある人曰く、
「そんなものはない。あるのは
関数プログラミングというスタイルだけだ」
「この...
よくある (かもしれない) 誤解

「ラムダ計算に基づく言語」は関数型言語
→ ラムダ式を持っていれば関数型言語だ?

今日はこの (ないかもしれない) 誤
解を解きに来ました!
ラムダ計算とは

すごくシンプルなプログラミング言語
文法がシンプル
予約語は λ だけ

関数しかない
真偽値も、数も、条件分岐も、ループも、全部関
数で表す

色々な関数型言語の基礎になっている
ラムダ計算の文法

ラムダ計算のプログラムは一つの項 (式と思って
もらえれば) として表されます
項の要素になれるのは、以下の 3 つだけです
名前 ・ ・ ・ ・
・ ・ ・ ・変数
・・・
(項 項) ・
・
・関数適用
(λ名前. 項)...
ラムダ計算の項として有効なもの

以下の文字列の並びは、ラムダ計算の項として有
効です
x
(f x)
(λx.x)
(λf.(λx.(f x)))
カッコの省略

.
(λf.(λx.(f x)))
.
の一番外側のカッコと一番内側のカッコは取り除
いても曖昧になりません。
.
λf.(λx.f x)
.
以降では、曖昧性のないカッコは省略します。
文法のおさらい
.
ラムダ計算の文法
.

.

t ::= < name >
| (< t > < t >)
| (λ < name > . < t >)
数値はおろか、真偽値などもない
変数が導入されるのはラムダ式の引数のみ
値はラムダ抽象...
ラムダ計算の意味

文法を定義しただけでは何の役にも立たない
ので、意味を与えてあげましょう!
ラムダ計算における計算
ラムダ計算における計算とは、引数に関数を適用
することです。
t1 t2 という項があった時に、t1 がラムダ抽象だっ
た場合に、ラムダ抽象の中の項に現れる引数を t2
で置き換えます。
.
例えばこんな
.
(λx.x...
簡約の方法

簡約の方法にはいろいろありますが、ここでは皆
さんになじみの深い方法を採用します。
t1 t2 という項があった時、
t1 から先に簡約する
t2 の簡約を終えてから、全体を簡約する
という方法で、
「値呼び戦略」と呼ばれます。
では・
・
・

文法が分かり、意味も与えたところで、実際にこ
れを使って計算してみましょう!
ラムダ計算で計算してみる
無理・
・
・

数も扱えないのにどうやって計算するんですか・
・
・
ということで、まずは道具を揃えましょう!
カリー化関数

ラムダ計算では複数引数を受け取る関数はないの
で、関数を返す関数をよく使います。
.
カリー化関数 λx.λy.x に λa.a と λb.b を渡す
.
(λx.λy.x) (λa.a) (λb.b)
−→ (λy.(λa.a...
カリー化関数の略記法

いちいちカリー化関数書くの面倒なので、略記法
を導入します。
.
上と下の記述は交換可能
.
λx.λy.t
λxy.t
.
真偽値

関数で表しましょう。
.
真偽値を表す関数
.
真:λtf.t
偽:λtf.f
.
なんでこれが真偽値?
真偽値 (2)
真が λtf.t、偽が λtf.f だったとして、
if cond then x else y を、cond x y とする
cond に真を入れてみる
((λtf.t) x) y
(λf.x) y
x

cond に偽を入れて...
自然数
真偽値同様、関数で表現します。
.
自然数を表す関数
.
0:λsz.z
1:λsz.s z
2:λsz.s (s z)
3:λsz.s (s (s z)))
.

z に s を何回適用するかで自然数を表します。
指で数を数えるのに似...
次の数を求める関数 succ

.
succ 関数
.
λn.λsz.s (n s z)
.
1. 自然数 n は λsz.t の形をしている
2. n に s と z を渡せば、t の部分が取り出せる
3. t にもう一回 s を適用すれば、...
足し算してみる
.
add 関数
.
λmn.λsz.m s (n s z)
.
1. 自然数 m は λsz.s (s (. . . (s z) . . . )) の形を
している (s は m 個)
2. 自然数 n は λsz.t の形を...
2+3

1. (λmn.λsz.m s (n s z)) (λsz.s (s z)) (λsz.s (s (s z)))
2. (λn.λsz.(λsz.s (s z)) s (n s z)) (λsz.s (s (s z)))
3. λsz...
掛け算してみる
.
mul 関数
.
λmn.λsz.m (n s) z
.
1. 自然数 n は λsz.s (s (. . . (s z) . . . )) の形をし
ている (s は n 個)
2. 自然数 n に s だけ適用したものは...
ぐるぐる∼

これを簡約してみましょう
.
(λx.x x) (λx.x x)
.
たのしい!
ラムダ計算を拡張してみる
ラムダ計算の拡張

さすがに、生のラムダ計算を扱うのはつらい
→拡張しましょう!
記法の拡張

2 + 3 を計算するだけで、
.
2+3
.
(λmn.λsz.m s (n s z)) (λsz. s (s z)) (λsz.s (s (s z))))
.
つらい・
・
・
数値の導入
数詞 (0 とか 1 とかそういうやつ) と関数で作った
自然数を対応付けることができる。
2 に対して λsz.s (s z)) を対応付けるようにすれ
ば、人間にとってよりわかりやすい!
ついでに、+ も λmn.λsz.m s...
真偽値の導入
ついでに真偽値も導入しましょう。
true と λtf.t を、f alse と λtf.f を対応付けます。
if-then-else も導入しましょう。
とりあえず、if cond then x else y を、cond x...
ふぅ・
・
・

ここまでで準備したものを使って、階乗を計算し
てみましょう!
階乗!
.
準備
.
Y = λg.(λx.g (x x)) (λx.g (x x))
g = λf n.if n = 0 then 1 else n ∗ (f (n − 1))
.
これをつかって、
.
3!をけいさん!
.
g (Y g) ...
まぁ、ずるしてるんですけどね!

Yってなんだよ
等値演算子定義してない
減算演算子定義してない
これらの理解や定義は各自の課題とする
この先

を読みましょう!
この発表は、第 5 章 (全 32 章) までをまとめた感じ
です
Upcoming SlideShare
Loading in...5
×

F#の基礎(嘘)

1,627

Published on

基礎勉強会忘年会で話せって言われたから過去の発表資料を改変してでっち上げたはいいが、結局時間がなくて発表できなかった資料です。せっかく作ったのであげておきます。

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,627
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
6
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Transcript of "F#の基礎(嘘)"

  1. 1. F#の基礎(嘘) bleis-tift December 7, 2013
  2. 2. 自己紹介 id:bleis-tift / @bleis なごやではたらくゆるふわ.NETer 好きな関数型言語は F# Microsoft MVP for Visual F#
  3. 3. なんか話せって言われたので・ ・ ・ 過去の基礎勉強会での発表を使い回しても問 題ないよねっ .NET 基礎での資料ほぼそのまま .NET と言えば F#(異論は認める F#の基礎と言えばラムダ計算ですよねー ということで (型無し) ラムダ計算の話です
  4. 4. 聞いたことある人は休憩時間です! ことりちゃんを愛でていればいいと思うよ!
  5. 5. 今日やること ラムダ計算って何? ラムダ計算で計算してみる 最終的には階乗を計算してみます
  6. 6. ラムダ計算って何?
  7. 7. その前に 関数型言語って何?
  8. 8. 関数型言語とは ある人曰く、 「それぞれの人が色々な特徴か ら適当なサブセットを選んで関数型と呼ぶ」 ある人曰く、 「永続的データ構造を扱う言 語だ」 ある人曰く、 「そんなものはない。あるのは 関数プログラミングというスタイルだけだ」 「この言語は関数型言語だ!」という判断は各人に 任せるとして、個人的には「ラムダ計算に基づく 言語」は関数型言語でいいのでは?と思ってます。
  9. 9. よくある (かもしれない) 誤解 「ラムダ計算に基づく言語」は関数型言語 → ラムダ式を持っていれば関数型言語だ? 今日はこの (ないかもしれない) 誤 解を解きに来ました!
  10. 10. ラムダ計算とは すごくシンプルなプログラミング言語 文法がシンプル 予約語は λ だけ 関数しかない 真偽値も、数も、条件分岐も、ループも、全部関 数で表す 色々な関数型言語の基礎になっている
  11. 11. ラムダ計算の文法 ラムダ計算のプログラムは一つの項 (式と思って もらえれば) として表されます 項の要素になれるのは、以下の 3 つだけです 名前 ・ ・ ・ ・ ・ ・ ・ ・変数 ・・・ (項 項) ・ ・ ・関数適用 (λ名前. 項)・ ・ ・ラムダ抽象 名前には、英字一文字を使うことが多いです。
  12. 12. ラムダ計算の項として有効なもの 以下の文字列の並びは、ラムダ計算の項として有 効です x (f x) (λx.x) (λf.(λx.(f x)))
  13. 13. カッコの省略 . (λf.(λx.(f x))) . の一番外側のカッコと一番内側のカッコは取り除 いても曖昧になりません。 . λf.(λx.f x) . 以降では、曖昧性のないカッコは省略します。
  14. 14. 文法のおさらい . ラムダ計算の文法 . . t ::= < name > | (< t > < t >) | (λ < name > . < t >) 数値はおろか、真偽値などもない 変数が導入されるのはラムダ式の引数のみ 値はラムダ抽象 (つまり関数) のみ!
  15. 15. ラムダ計算の意味 文法を定義しただけでは何の役にも立たない ので、意味を与えてあげましょう!
  16. 16. ラムダ計算における計算 ラムダ計算における計算とは、引数に関数を適用 することです。 t1 t2 という項があった時に、t1 がラムダ抽象だっ た場合に、ラムダ抽象の中の項に現れる引数を t2 で置き換えます。 . 例えばこんな . (λx.x) (λy.λz.(y z)) ↓下線を引いた項に引数を与えて簡約 λy.λz.(y z) .
  17. 17. 簡約の方法 簡約の方法にはいろいろありますが、ここでは皆 さんになじみの深い方法を採用します。 t1 t2 という項があった時、 t1 から先に簡約する t2 の簡約を終えてから、全体を簡約する という方法で、 「値呼び戦略」と呼ばれます。
  18. 18. では・ ・ ・ 文法が分かり、意味も与えたところで、実際にこ れを使って計算してみましょう!
  19. 19. ラムダ計算で計算してみる
  20. 20. 無理・ ・ ・ 数も扱えないのにどうやって計算するんですか・ ・ ・ ということで、まずは道具を揃えましょう!
  21. 21. カリー化関数 ラムダ計算では複数引数を受け取る関数はないの で、関数を返す関数をよく使います。 . カリー化関数 λx.λy.x に λa.a と λb.b を渡す . (λx.λy.x) (λa.a) (λb.b) −→ (λy.(λa.a)) (λb.b) −→ λa.a . λx.(λy.x) 自体は関数を返す関数だけど、2 つの引 数をとる関数と同じような働きをする!
  22. 22. カリー化関数の略記法 いちいちカリー化関数書くの面倒なので、略記法 を導入します。 . 上と下の記述は交換可能 . λx.λy.t λxy.t .
  23. 23. 真偽値 関数で表しましょう。 . 真偽値を表す関数 . 真:λtf.t 偽:λtf.f . なんでこれが真偽値?
  24. 24. 真偽値 (2) 真が λtf.t、偽が λtf.f だったとして、 if cond then x else y を、cond x y とする cond に真を入れてみる ((λtf.t) x) y (λf.x) y x cond に偽を入れてみる ((λtf.f ) x) y (λf.f ) y y 真偽値として働いている!
  25. 25. 自然数 真偽値同様、関数で表現します。 . 自然数を表す関数 . 0:λsz.z 1:λsz.s z 2:λsz.s (s z) 3:λsz.s (s (s z))) . z に s を何回適用するかで自然数を表します。 指で数を数えるのに似てますね。
  26. 26. 次の数を求める関数 succ . succ 関数 . λn.λsz.s (n s z) . 1. 自然数 n は λsz.t の形をしている 2. n に s と z を渡せば、t の部分が取り出せる 3. t にもう一回 s を適用すれば、次の数になる!
  27. 27. 足し算してみる . add 関数 . λmn.λsz.m s (n s z) . 1. 自然数 m は λsz.s (s (. . . (s z) . . . )) の形を している (s は m 個) 2. 自然数 n は λsz.t の形をしている (t には n 個の s が含まれる) 3. 自然数 m の z 部分を n の t 部分に入れ替え れば、足し算ができる!
  28. 28. 2+3 1. (λmn.λsz.m s (n s z)) (λsz.s (s z)) (λsz.s (s (s z))) 2. (λn.λsz.(λsz.s (s z)) s (n s z)) (λsz.s (s (s z))) 3. λsz.(λsz.s (s z)) s ((λsz.s (s (s z))) s z)
  29. 29. 掛け算してみる . mul 関数 . λmn.λsz.m (n s) z . 1. 自然数 n は λsz.s (s (. . . (s z) . . . )) の形をし ている (s は n 個) 2. 自然数 n に s だけ適用したものは、引数に s を n 回適用する関数になる 3. それを自然数 m の s として渡すので、s を n 回適用したものが m 個作られる 4. それに z を渡してあげれば、 m と n を掛け合わせた結果の自然数になる!
  30. 30. ぐるぐる∼ これを簡約してみましょう . (λx.x x) (λx.x x) . たのしい!
  31. 31. ラムダ計算を拡張してみる
  32. 32. ラムダ計算の拡張 さすがに、生のラムダ計算を扱うのはつらい →拡張しましょう!
  33. 33. 記法の拡張 2 + 3 を計算するだけで、 . 2+3 . (λmn.λsz.m s (n s z)) (λsz. s (s z)) (λsz.s (s (s z)))) . つらい・ ・ ・
  34. 34. 数値の導入 数詞 (0 とか 1 とかそういうやつ) と関数で作った 自然数を対応付けることができる。 2 に対して λsz.s (s z)) を対応付けるようにすれ ば、人間にとってよりわかりやすい! ついでに、+ も λmn.λsz.m s (n s z) に対応付け てしまえば、2 + 3 はそのまま、 . 2 . +3 と記述できる! n に 2 を足す関数なら、 . λ . n.n + 2 分かりやすい!
  35. 35. 真偽値の導入 ついでに真偽値も導入しましょう。 true と λtf.t を、f alse と λtf.f を対応付けます。 if-then-else も導入しましょう。 とりあえず、if cond then x else y を、cond x y に対応付けましょう。 . if-then-else を使った例 . λ . bmn.if b then m + n else m ∗ n b が真なら m + n を、偽なら m ∗ n を計算する 関数
  36. 36. ふぅ・ ・ ・ ここまでで準備したものを使って、階乗を計算し てみましょう!
  37. 37. 階乗! . 準備 . Y = λg.(λx.g (x x)) (λx.g (x x)) g = λf n.if n = 0 then 1 else n ∗ (f (n − 1)) . これをつかって、 . 3!をけいさん! . g (Y g) 3 if 3 = 0 then 1 else 3 ∗ ((Y g) (3 − 1)) 3 ∗ (if 2 = 0 then 1 else 2 ∗ ((Y g) (2 − 1))) 3 ∗ 2 ∗ (if 1 = 0 then 1 else 1 ∗ ((Y g) (1 − 1))) 3 ∗ 2 ∗ 1 ∗ (if 0 = 0 then 1 else 0 ∗ ((Y g) (0 − 1))) 3 . ∗2∗1∗1 できました!
  38. 38. まぁ、ずるしてるんですけどね! Yってなんだよ 等値演算子定義してない 減算演算子定義してない これらの理解や定義は各自の課題とする
  39. 39. この先 を読みましょう! この発表は、第 5 章 (全 32 章) までをまとめた感じ です
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×