狠狠撸

狠狠撸Share a Scribd company logo
Swi$による
関数型プログラミング
超入門
2015年11月14日
藤本尚邦 / Cocoa勉強会(関東) #75
1
自己紹介
? 藤本尚邦 (@%isa)
? h+ps://github.com/%isa
? フリーランスプログラマー
? RubyCocoaフレームワーク原作者
? Mac開発歴、薄く長く約25年
? iOS開発歴、約1年
2
アジェンダ
? 始めに
? 総和?総乗
? 総和?総乗の抽象化
? SequenceTypeプロトコル
? 関数型プログラミングとは
? まとめ
3
始めに
? 関数型プログラミング1
ってよく聞くけど何それ?
? C言語には関数があるから関数型プログラミング
ができるの?
? map とか reduce って何?どうやって使うの?
このような立ち位置の人を想定して、関数型プログ
ラミング風の考え方の一端を紹介します。
1
英語で Fanc%onal Programming といいます。短縮して FP と呼ばれています。
4
始めに
私自身は、語れるほどFPを理解しているわけではあ
りません。ただし、以前自分でもそれと気付かずに
FPを学んだことがあります。
その経験をもとに発表の構成を考えました。
5
総和?総乗
6
総和?総乗
定義1:
7
総和?総乗
func sum(n: Int) -> Int {
var accumulator = 0
for i in 1...n { accumulator += i }
return accumulator
}
func prod(n: Int) -> Int {
var accumulator = 1
for i in 1...n { accumulator *= i }
return accumulator
}
ループと代入を使った手続き的なプログラム
8
総和?総乗
定義2:
9
総和?総乗
func sum(n: Int) -> Int {
return n == 0 ? 0 : n + sum(n - 1)
}
func prod(n: Int) -> Int {
return n == 0 ? 1 : n * prod(n - 1)
}
再帰呼出を使ったFPの香り漂うプログラム
10
総和 (番外編)
ガウス(小3)による総和のプログラム:
func sum(n: Int) -> Int {
return n * (n + 1) / 2
}
総和についてはガウスの方法が賢いやり方だが、総
乗への応用は多分きかない。
11
総和?総乗の抽象化
12
総和?総乗の抽象化
2つの関数の似ている点?違う点を探してみよう:
func sum(n: Int) -> Int {
return n == 0 ? 0 : n + sum(n - 1)
}
func prod(n: Int) -> Int {
return n == 0 ? 1 : n * prod(n - 1)
}
13
総和?総乗の抽象化
2つの関数の違う点:
? n==0のとき、前者は0を返し後者は1を返す
? n!=0のとき、前者は足し算で後者は掛け算
14
総和?総乗の抽象化
元の引数nに加えて、総和?総乗で違う以下の2点:
? n==0のときの値 (初期値)
? n!=0のときの計算 (関数)
を引数にすれば、同じパターンの計算に使えるより
汎用的な関数が出来上がるはずです。
15
総和?総乗の抽象化
typealias IntCombinator = (Int, Int) -> Int
func reduce(n: Int, initial: Int, combine: IntCombinator) -> Int
{
if n == 0 {
return initial
} else {
return combine(
n,
reduce(n - 1, initial: initial, combine: combine))
}
}
総和?総乗のパターンを抽象化した関数 reduce
16
総和?総乗の抽象化
関数reduceを使って総和?総乗を計算してみよう:
// ふたつの整数の和算?乗算をする関数を定義
func add2(n: Int, m: Int) -> Int { return n + m }
func mul2(n: Int, m: Int) -> Int { return n * m }
reduce(10, initial: 0, combine: add2)
reduce(10, initial: 1, combine: mul2)
17
総和?総乗の抽象化
関数reduceを使って総和?総乗を計算してみよう(2):
// 無名関数(関数リテラル)を直接渡す
reduce(10, initial: 0, combine: { $0 + $1 })
reduce(10, initial: 1, combine: { $0 * $1 })
// Ruby風シンタックスシュガー
reduce(10, initial: 0) { $0 + $1 }
reduce(10, initial: 1) { $0 * $1 }
18
総和?総乗の抽象化
Swi$では + や - も関数なので引数に渡せます:
// モダンな関数型プログラミング風
reduce(10, initial: 0, combine: +)
reduce(10, initial: 1, combine: *)
add2 や mul2 のような関数を定義する必要はありま
せんでした。
19
総和?総乗の抽象化
ここまで、関数 reduce の定義にいたる道筋を示す
ことで、関数型プログラミングの考え方の土台を簡
単に紹介しました。
今回は、関数を引数にとる関数を題材にしました
が、関数を返す関数を使ったプログラミングなどさ
らに奥深い世界が存在しています。
20
SequenceTypeプロトコル
21
SequenceTypeプロトコル
for item in collection {
statements
}
Swi$の For-In構文では、繰り返しの対象となる
collection が SequenceType プロトコルに適合
している必要があります。
22
SequenceTypeプロトコル
代表的なインスタンスメソッド:
? filter
? map
? reduce
? sort
23
SequenceTypeプロトコル
filter
引数で与えられた関数で各itemを調べ、trueを返
したitemのみによる配列を返します。
(1...10).filter { $0 % 2 == 0 } // => [2, 4, 6, 8, 10]
(1...10).filter { $0 % 2 != 0 } // => [1, 3, 5, 7, 9]
24
SequenceTypeプロトコル
map
数学で写像(mapping)と呼ばれているものに相当しま
す。各itemに関数を適用した結果の配列を返しま
す。
(1...5).map { $0 * 2 } // => [2, 4, 6, 8, 10]
(1...5).map { String($0) } // => ["1", "2", "3", "4", "5"]
(1...5).map(String.init) // => ["1", "2", "3", "4", "5"]
25
SequenceTypeプロトコル
reduce
現実的?汎用的な本物のreduceです23
。
(1...10).reduce(0, combine: +) // Swift的な総和の計算
(1...10).reduce(1, combine: *) // Swift的な総乗の計算
["aa", "bb", "cc"].reduce("") { "($0)/($1)" }
// => "/aa/bb/cc"
3
言語によっては inject (Ruby, Smalltalkなど) や fold (Haskellなど) と呼ばれています。
2
SequenceTypeではitemの型も変数なので、Int型に限定せず扱うことができます。
26
SequenceTypeプロトコル
sort
itemを比較関数で並べ変えた配列を返します。item
がComparableプロトコルに適合している場合は、
比較関数を省略できます。
[5,4,3,2,1].sort() // => [1, 2, 3, 4, 5]
(1...5).sort(>) // => [5, 4, 3, 2, 1]
27
SequenceTypeプロトコル
次のようなPersonと名簿が定義されているとします:
struct Person {
let name: String
let age: Int
let sex: Sex
enum Sex { case Male, Female, Others }
}
let BABYMETAL: [Person] = [
Person(name: "中元すず香", age: 17, sex: .Female),
Person(name: "菊地最愛", age: 16, sex: .Female),
Person(name: "水野由結", age: 16, sex: .Female),
Person(name: "青山英樹", age: 29, sex: .Male),
Person(name: "BOH", age: 33, sex: .Male),
Person(name: "大村孝佳", age: 31, sex: .Male),
Person(name: "藤岡幹大", age: 34, sex: .Male),
]
28
SequenceTypeプロトコル
//: BABYMETAL女子の名前
BABYMETAL
.filter { $0.sex == .Female }
.map { $0.name }
//: BABYMETAL全員の平均年齢
Float(BABYMETAL
.map { $0.age }
.reduce(0, combine: +)) / Float(BABYMETAL.count)
29
関数型プログラミングとは
30
関数型プログラミングとは
Swi$の特徴4
:
? 関数がファーストクラスオブジェクト
? 関数を引数や返り値として扱える
? 関数と普通の変数の名前空間が一緒
4
JavaScript はこの特徴を持つプログラミング言語の代表例
31
関数型プログラミングとは
代入を使わない限り、同じ引数による同じ手続きの
呼び出しは2回評価しても同じ結果になるので、手
続きは数学関数の計算とみなすことができる…まっ
たく代入を使わないプログラミングは、そのため関
数型プログラミング(func%onal programming)と呼ばれ
ている。
— Structure and Interpreta%on of Computer Programs
(真鍋宏史日本語訳版) より
32
関数型プログラミングとは
「計算機プログラムの構造と解釈」(通称SICP):
1. 手続きを用いた抽象化の構築 (高階関数)
2. データを用いた抽象化の構築 (データ構造)
3. モジュール性、オブジェクト、状態 (代入初登場)
4. メタ言語抽象化 (プログラミング言語の実装)
5. レジスタマシンによる計算 (CPU?コンパイラ)
33
まとめ
Swi$は手続き型プログラミングと関数型プログラミ
ングの双方のメリットを利用できるバランスの良い
言語です。大いに活用しましょう!
34
参考文献
? Structure and Interpreta.on of Computer Programs
(SICP) 真鍋宏史日本語訳版
? The Swi< Programming Language (Swi< 2.1)
? Swi< Standard Library Reference
35
Thank you!2015年11月14日
藤本尚邦 / Cocoa勉強会(関東) #75
36

More Related Content

What's hot (20)

PDF
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
Yoshiro Tokumasu
?
PDF
ビッグデータ処理データベースの全体像と使い分け
Recruit Technologies
?
PDF
TLS, HTTP/2演習
shigeki_ohtsu
?
PDF
ルータコンフィグのGit管理のススメ ?Git管理以外を自動化してみた?
Taiji Tsuchiya
?
PPTX
フロー技术によるネットワーク管理
Motonori Shindo
?
PDF
Amazon ElastiCacheのはじめ方
Amazon Web Services Japan
?
PDF
SkyWayを使いこなすために How to use SkyWay -SkyWay UG Kansai #1 スペシャルバージョン-
Yusuke Naka
?
PDF
Automated Provisioning, Management & Cost Control for Kubernetes Clusters
Weaveworks
?
PPTX
がっつり惭辞苍驳辞顿叠事例绍介
Tetsutaro Watanabe
?
PDF
Akkaとは。アクターモデル とは。
Kenjiro Kubota
?
PPTX
GraalVM を普通の Java VM として使う ~クラウドベンチマークなどでの比較~
Shinji Takao
?
PPTX
罢补产濒别补耻のつまづきポイント
Shinji Tamura
?
PDF
Ansible2.9 ネットワーク対応のアップデート #ansiblejp
akira6592
?
PDF
30分でわかる! コンピュータネットワーク
Trainocate Japan, Ltd.
?
PPTX
惭测厂蚕尝や厂厂顿とかの话?前编
gree_tech
?
PDF
分散システムの限界について知ろう
Shingo Omura
?
PDF
20160215 04 java ee7徹底入門 jbatch
Jun Inose
?
PDF
Apache Airflow 概要(Airflowの基礎を学ぶハンズオンワークショップ 発表資料)
NTT DATA Technology & Innovation
?
PPTX
搁贵颁5996(滨碍贰惫2)第2版
Tetsuya Hasegawa
?
PPTX
Java11へのマイグレーションガイド ~Apache Hadoopの事例~
驰补丑辞辞!デベロッパーネットワーク
?
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
Yoshiro Tokumasu
?
ビッグデータ処理データベースの全体像と使い分け
Recruit Technologies
?
TLS, HTTP/2演習
shigeki_ohtsu
?
ルータコンフィグのGit管理のススメ ?Git管理以外を自動化してみた?
Taiji Tsuchiya
?
フロー技术によるネットワーク管理
Motonori Shindo
?
Amazon ElastiCacheのはじめ方
Amazon Web Services Japan
?
SkyWayを使いこなすために How to use SkyWay -SkyWay UG Kansai #1 スペシャルバージョン-
Yusuke Naka
?
Automated Provisioning, Management & Cost Control for Kubernetes Clusters
Weaveworks
?
がっつり惭辞苍驳辞顿叠事例绍介
Tetsutaro Watanabe
?
Akkaとは。アクターモデル とは。
Kenjiro Kubota
?
GraalVM を普通の Java VM として使う ~クラウドベンチマークなどでの比較~
Shinji Takao
?
罢补产濒别补耻のつまづきポイント
Shinji Tamura
?
Ansible2.9 ネットワーク対応のアップデート #ansiblejp
akira6592
?
30分でわかる! コンピュータネットワーク
Trainocate Japan, Ltd.
?
惭测厂蚕尝や厂厂顿とかの话?前编
gree_tech
?
分散システムの限界について知ろう
Shingo Omura
?
20160215 04 java ee7徹底入門 jbatch
Jun Inose
?
Apache Airflow 概要(Airflowの基礎を学ぶハンズオンワークショップ 発表資料)
NTT DATA Technology & Innovation
?
搁贵颁5996(滨碍贰惫2)第2版
Tetsuya Hasegawa
?
Java11へのマイグレーションガイド ~Apache Hadoopの事例~
驰补丑辞辞!デベロッパーネットワーク
?

Viewers also liked (8)

PDF
厂飞颈蹿迟て?の関数型フ?ロク?ラミンク?について考えていること
Shingo Sato
?
PPTX
厂飞颈蹿迟で説明する「モナド」:厂飞颈蹿迟における関数型プログラミングの使い方
Roy Kim
?
PDF
Kana-Kanji Conversion using N-gram
takeda25
?
PDF
Ngram kana-kanji conversion with grammatical annotations
takeda25
?
PPTX
Accumulate-Discount algorithm for Linear-Chain CRFs
takeda25
?
PDF
graduate_thesis (1)
Sihan Chen
?
PPT
Variable-Order CRFs
takeda25
?
PDF
The state of sbt 0.13, sbt server, and sbt 1.0 (ScalaSphere ver)
Eugene Yokota
?
厂飞颈蹿迟て?の関数型フ?ロク?ラミンク?について考えていること
Shingo Sato
?
厂飞颈蹿迟で説明する「モナド」:厂飞颈蹿迟における関数型プログラミングの使い方
Roy Kim
?
Kana-Kanji Conversion using N-gram
takeda25
?
Ngram kana-kanji conversion with grammatical annotations
takeda25
?
Accumulate-Discount algorithm for Linear-Chain CRFs
takeda25
?
graduate_thesis (1)
Sihan Chen
?
Variable-Order CRFs
takeda25
?
The state of sbt 0.13, sbt server, and sbt 1.0 (ScalaSphere ver)
Eugene Yokota
?
Ad

Similar to 厂飞颈蹿迟による関数型フ?ロク?ラミンク?超入门 (20)

ODP
フ?ロク?ラミンク?言语颁测补苍の绍介
baban ba-n
?
PDF
【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 2 章
YOSHIKAWA Ryota
?
PDF
Swift を振り返ってみよう #cswift
Tomohiro Kumagai
?
PDF
Cookpad 17 day Tech internship 2017 言語処理系入門 Rubyをコンパイルしよう
Koichi Sasada
?
PDF
厂飞颈蹿迟で搁颈别尘补苍苍球面を扱う
hayato iida
?
PDF
ちゃんとWeb会議スライド『Coffee script』
H2O Space. Co., Ltd.
?
PDF
渋谷JVM#1 Immutable時代のプログラミング言語 Clojure
Yoshitaka Kawashima
?
PDF
普通のプログラミング言语搁
Shuyo Nakatani
?
PDF
厂肠补濒补で萌える関数型プログラミング摆完全版闭
Ra Zon
?
PPTX
コードの自动修正によって実现する、机能开発を止めないフレームワーク移行
gree_tech
?
PPTX
関数型言语&补尘辫;形式的手法セミナー(3)
啓 小笠原
?
PDF
2015.08.29 JUS共催勉強会資料
umidori
?
PDF
谤耻产测-蹿蹿颈についてざっくり解説
ota42y
?
PDF
関数プログラミング入门
masatora atarashi
?
PDF
do Notation Equivalents in JVM languages: Scala, Kotlin, Clojure
Kent Ohashi
?
PDF
Pyconjp2014_implementations
masahitojp
?
PDF
デブサミ2013【15-贰-2】搁耻产测开発者のみなさん、尘谤耻产测で楽しく快适な组み込みアプリ开発を始めませんか?
Developers Summit
?
PDF
笔贬笔の関数実行とその计测
shinjiigarashi
?
PDF
Getting Started GraalVM (再アップロード)
tamtam180
?
PDF
Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2
tamtam180
?
フ?ロク?ラミンク?言语颁测补苍の绍介
baban ba-n
?
【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 2 章
YOSHIKAWA Ryota
?
Swift を振り返ってみよう #cswift
Tomohiro Kumagai
?
Cookpad 17 day Tech internship 2017 言語処理系入門 Rubyをコンパイルしよう
Koichi Sasada
?
厂飞颈蹿迟で搁颈别尘补苍苍球面を扱う
hayato iida
?
ちゃんとWeb会議スライド『Coffee script』
H2O Space. Co., Ltd.
?
渋谷JVM#1 Immutable時代のプログラミング言語 Clojure
Yoshitaka Kawashima
?
普通のプログラミング言语搁
Shuyo Nakatani
?
厂肠补濒补で萌える関数型プログラミング摆完全版闭
Ra Zon
?
コードの自动修正によって実现する、机能开発を止めないフレームワーク移行
gree_tech
?
関数型言语&补尘辫;形式的手法セミナー(3)
啓 小笠原
?
2015.08.29 JUS共催勉強会資料
umidori
?
谤耻产测-蹿蹿颈についてざっくり解説
ota42y
?
関数プログラミング入门
masatora atarashi
?
do Notation Equivalents in JVM languages: Scala, Kotlin, Clojure
Kent Ohashi
?
Pyconjp2014_implementations
masahitojp
?
デブサミ2013【15-贰-2】搁耻产测开発者のみなさん、尘谤耻产测で楽しく快适な组み込みアプリ开発を始めませんか?
Developers Summit
?
笔贬笔の関数実行とその计测
shinjiigarashi
?
Getting Started GraalVM (再アップロード)
tamtam180
?
Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2
tamtam180
?
Ad

厂飞颈蹿迟による関数型フ?ロク?ラミンク?超入门