SlideShare a Scribd company logo
関数プログラミング
ことはじめ (再)
Scala 関西 Summit 2018
おことわり
• Scala関西 Summit 2017で木虎直樹さんによっ
て行なわれたハンズオンの再演です
• 2016, 2015 でも行ないました
• 厳密な正確性よりもわかりやすさを重視
• 資料: https://bit.ly/scalaks2018ho
Scala 難しい

という意見を聞くことがあります。
Scala は本当に難しい?
複数の要因を一緒にして
いない?
•Scala の言語仕様が難しい
•関数プログラミングが難しい
•型システムが難しい
Scala の難しさって?
•関数プログラミングが難しい
• 命令プログラミングのパラダイムとい
う先入観をもって、関数プログラミン
グのパラダイムを学ぶ難しさ
• 関数型言語が基礎とする数学概念の難
しさ
• プログラミングの難しさ
本日のテーマ
•関数プログラミングが難しい
• 命令プログラミングのパラダイムとい
う先入観をもって、関数プログラミン
グのパラダイムを学ぶ難しさ
• 関数型言語が基礎とする数学概念の難
しさ
• プログラミングの難しさ
本日のテーマ
関数プログラミングのパラダ
イムを理解するきっかけを掴
む
本日のゴール
関数プログラミングの関数
数学でいうところの関数
f(x) = x + 1
だから Scala では
•関数定義に = (イコール) を使用
•関数内で最後に評価された値が返る
Which
is
better?
def f(x: Int) {x + 1}
def f(x: Int) = x + 1
def f(x: Int) = return x + 1
※注: 上の 2つは正しいコードではありません。
関数プログラミング (狭義)
• 変更可能 (mutable) な変数
• 再代入
• ループなどの命令型の制御
を使わずにプログラミングすること
お願い
現時点での関数プログラミングに対する疑問を
教えてください。
命令プログラマの疑問
再代入やループなしにどうやって書くのか?
int sum = 0;
for (int i = 0; i < array.length; i++) {
sum += array[i];
}
return sum;
命令プログラミング
具体的な手順を記述
関数プログラミング
対象の性質を定義
プログラミングの関心事
関数プログラミングでの問題へのアプローチ
問題を抽象化・一般化
準備
• https://bit.ly/scalaks2018intellij
• IntelliJ のセットアップが上手くいかな
い場合はこちら
• https://bit.ly/scalaks2018jupy (ハンズ
オンのJupyter notebook)
• https://scastie.scala-lang.org/ (Web
ブラウザー上でScalaを実行)
問題
ある自然数を引数にとり、当該自然
数以下の自然数の合計を返す関数を
定義せよ
命令プログラミング
• 1からnまでカウントアップ
• カウントアップした数字を足し込んでいく
int f(int n) {
int total = 0;
for (int i = 1; i <= n; i++) {
total += i;
}
return total;
}
例示して性質を抽出
f(1) = 1
f(2) = 1 + 2
f(3) = 1 + 2 + 3
...
f(n) = 1 + 2 + 3 + ... + n
具体から抽象へ
f(1) = 1
f(2) = f(1) + 2
f(3) = f(2) + 3
...
f(n) = f(n - 1) + n
f(1) = 1
f(n) = f(n - 1) + n
def f(n: Int): Int =
if (n == 1) 1
else f(n - 1) + n
f(1) = 1
f(n) = f(n - 1) + n
問題
指定された自然数の階乗を返す関数
を定義せよ
階乗
f(0) = 1
f(1) = 1
f(2) = 2 * 1
f(3) = 3 * 2 * 1
...
f(n) = n * ... * 3 * 2 * 1
階乗 (一般化)
f(0) = 1
f(1) = 1 * f(0)
f(2) = 2 * f(1)
f(3) = 3 * f(2)
...
f(n) = n * f(n - 1)
f(0) = 1
f(n) = n * f(n - 1)
def f(n: Int): Int =
if (n == 0) 1
else n * f(n - 1)
フィボナッチ数列の n 項目の値を返
す関数の定義は?
1, 1, 2, 3, 5, 8, 13, …
フィボナッチ数
f(0) = 0
f(1) = 1
f(2) = 0 + 1
f(3) = 1 + 1
f(4) = 1 + 2
f(5) = 2 + 3
...
フィボナッチ数
f(0) = 0
f(1) = 1
f(2) = f(0) + f(1)
f(3) = f(1) + f(2)
f(4) = f(2) + f(3)
f(5) = f(3) + f(4)
...
f(n) = f(n - 2) + f(n - 1)
f(0) = 0
f(1) = 1
f(n) = f(n - 2) + f(n - 1)
def f(n: Int): Int =
if (n == 0) 0
else if (n == 1) 1
else f(n - 2) + f(n - 1)
問題
指定されたリスト内の数の合計を返す
関数 sum を定義せよ
def sum(ints: List[Int]): Int
リストの定義
•空リスト Nil はリスト
•head が要素、tail がリストなら
head :: tail もリスト
3
Nil
Nil::
3 :: Nil2 ::
2 :: 3 :: Nil1 ::
自身を使って定義されたデータ型
•再帰的なデータ型
•自己参照をするデータ型
再帰的なデータ構造の場合は

その構造に沿って計算する
データ構造
Nil
Nil::8
8 :: Nil::2
2 :: 8 :: Nil::1
1 :: 2 :: 8 :: Nil::5
5 :: 1 :: 2 :: 8 :: Nil
例示
sum(5 :: 1 :: 2 :: 8 :: Nil)
sum( )

= + sum( )
sum( ) = + sum( )
sum( ) = + sum( )
sum( ) = + sum( )
sum( ) = 0Nil
8 :: Nil
2 :: 8 :: Nil
5 :: 1 :: 2 :: 8 :: Nil
Nil8
8 :: Nil2
2 :: 8 :: Nil1
5 1 :: 2 :: 8 :: Nil
1 :: 2 :: 8 :: Nil
一般化
sum( ) = + sum( )
sum( ) = + sum( )
sum( ) = + sum( )
sum( ) = 0Nil
8 :: Nil
2 :: 8 :: Nil
Nil8
8 :: Nil22 :: 8 :: Nil
1
要素
head
リスト
要素
head
リスト
tail
リスト
要素
head
リスト
tail
リスト
head が要素、tail がリストなら head :: tail もリスト
1 :: 2 :: 8 :: Nil
リスト
リスト
tail
sum(Nil) = 0
sum(head :: tail) = head + sum(tail)
def sum(list: List[Int]): Int =
if (list.isEmpty) 0
else list.head + sum(list.tail)
def sum(list: List[Int]): Int = list match {
case Nil => 0
case head :: tail => head + sum(tail)
}
問題
指定されたリスト内の数を掛け合わせ
た値を返す関数 product を定義せよ
def product(ints: List[Int]): Int
問題
指定されたリスト内の最大値を返す関
数 max を定義せよ
def max(ints: List[Int]): Int
問題
指定されたリストを逆順に並び替えて
返す関数 reverse を定義せよ
def reverse(ints: List[Int]): List[Int]
問題
指定されたリストの長さを返す関数
length を定義せよ
def length(ints: List[Int]): Int
末尾再帰
def sum(list: List[Int]): Int = list match {
case Nil => 0
case head :: tail => head + sum(tail)
}
def sum(list: List[Int]): Int = {
def loop(acc: Int, l: List[Int]): Int = l match {
case Nil => acc
case head :: tail => loop(acc + head, tail)
}
loop(0, list)
}
命令プログラミング
具体的な手順を記述
関数プログラミング
対象の性質を定義
プログラミングの関心事
お薦めのリソース
• Functional Programming Principles in Scala

Scala の作者である Martin Odersky 教授によ
る関数プログラミングの講義

https://www.coursera.org/course/progfun
• プログラミングの基礎

言語は OCaml だが関数プログラミングの入門
書としては良書

http://www.amazon.co.jp/dp/4781911609
• Scala関数型デザイン&プログラミング ―
Scalazコントリビューターによる関数型徹底
ガイド

前の 2つよりも難易度は高い。

http://www.amazon.co.jp/dp/4844337769
その他のおすすめ2018版
• (関数プログラミングに限らず)
• 実践Scala入門

https://www.amazon.co.jp/dp/4297101416/
• Scalaをはじめよう! ─マルチパラダイム言語
への招待─

https://nextpublishing.jp/book/9497.html

More Related Content

What's hot

ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体
digitalghost
 
解説#74 連結リスト
解説#74 連結リスト解説#74 連結リスト
解説#74 連結リスト
Ruo Ando
 
Freer Monads, More Extensible Effects
Freer Monads, More Extensible EffectsFreer Monads, More Extensible Effects
Freer Monads, More Extensible Effects
Hiromi Ishii
 
たのしい高階関数
たのしい高階関数たのしい高階関数
たのしい高階関数
Shinichi Kozake
 
10min r study_tokyor25
10min r study_tokyor2510min r study_tokyor25
10min r study_tokyor25Nobuaki Oshiro
 
C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020
C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020
C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020
Fujio Kojima
 
関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml
Haruka Oikawa
 
Metaprogramming in JuliaLang
Metaprogramming in JuliaLangMetaprogramming in JuliaLang
Metaprogramming in JuliaLang
Yuichi Motoyama
 
関数の近似方法(MATLAB)
関数の近似方法(MATLAB)関数の近似方法(MATLAB)
関数の近似方法(MATLAB)
Tsuyoshi Horigome
 
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISる
Hideyuki Tanaka
 
"What Does Your Code Smell Like?"で学ぶPerl6
"What Does Your Code Smell Like?"で学ぶPerl6"What Does Your Code Smell Like?"で学ぶPerl6
"What Does Your Code Smell Like?"で学ぶPerl6
risou
 
Lisp講義1
Lisp講義1Lisp講義1
Java初心者勉強会(2015/08/07)資料
Java初心者勉強会(2015/08/07)資料Java初心者勉強会(2015/08/07)資料
Java初心者勉強会(2015/08/07)資料
Toshio Ehara
 
Real World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたReal World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたblackenedgold
 
おいしいLisp
おいしいLispおいしいLisp
おいしいLisp
Kent Ohashi
 
Functional Way
Functional WayFunctional Way
Functional Way
Kent Ohashi
 
Java電卓勉強会資料
Java電卓勉強会資料Java電卓勉強会資料
Java電卓勉強会資料Toshio Ehara
 
Intoroduction of Pandas with Python
Intoroduction of Pandas with PythonIntoroduction of Pandas with Python
Intoroduction of Pandas with PythonAtsushi Hayakawa
 
Julia is your friend (Japanese)
Julia is your friend (Japanese)Julia is your friend (Japanese)
Julia is your friend (Japanese)
home
 
CLR/H No.35-2
CLR/H No.35-2CLR/H No.35-2
CLR/H No.35-2
Nobuhisa Koizumi
 

What's hot (20)

ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体
 
解説#74 連結リスト
解説#74 連結リスト解説#74 連結リスト
解説#74 連結リスト
 
Freer Monads, More Extensible Effects
Freer Monads, More Extensible EffectsFreer Monads, More Extensible Effects
Freer Monads, More Extensible Effects
 
たのしい高階関数
たのしい高階関数たのしい高階関数
たのしい高階関数
 
10min r study_tokyor25
10min r study_tokyor2510min r study_tokyor25
10min r study_tokyor25
 
C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020
C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020
C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020
 
関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml
 
Metaprogramming in JuliaLang
Metaprogramming in JuliaLangMetaprogramming in JuliaLang
Metaprogramming in JuliaLang
 
関数の近似方法(MATLAB)
関数の近似方法(MATLAB)関数の近似方法(MATLAB)
関数の近似方法(MATLAB)
 
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISる
 
"What Does Your Code Smell Like?"で学ぶPerl6
"What Does Your Code Smell Like?"で学ぶPerl6"What Does Your Code Smell Like?"で学ぶPerl6
"What Does Your Code Smell Like?"で学ぶPerl6
 
Lisp講義1
Lisp講義1Lisp講義1
Lisp講義1
 
Java初心者勉強会(2015/08/07)資料
Java初心者勉強会(2015/08/07)資料Java初心者勉強会(2015/08/07)資料
Java初心者勉強会(2015/08/07)資料
 
Real World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたReal World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみた
 
おいしいLisp
おいしいLispおいしいLisp
おいしいLisp
 
Functional Way
Functional WayFunctional Way
Functional Way
 
Java電卓勉強会資料
Java電卓勉強会資料Java電卓勉強会資料
Java電卓勉強会資料
 
Intoroduction of Pandas with Python
Intoroduction of Pandas with PythonIntoroduction of Pandas with Python
Intoroduction of Pandas with Python
 
Julia is your friend (Japanese)
Julia is your friend (Japanese)Julia is your friend (Japanese)
Julia is your friend (Japanese)
 
CLR/H No.35-2
CLR/H No.35-2CLR/H No.35-2
CLR/H No.35-2
 

Similar to 関数プログラミング ことはじめ (再)

たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
Shinichi Kozake
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3
Ransui Iso
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
Nobuhisa Koizumi
 
Rあんなときこんなとき(tokyo r#12)
Rあんなときこんなとき(tokyo r#12)Rあんなときこんなとき(tokyo r#12)
Rあんなときこんなとき(tokyo r#12)Shintaro Fukushima
 
関数型都市忘年会『はじめての函数型プログラミング』
関数型都市忘年会『はじめての函数型プログラミング』関数型都市忘年会『はじめての函数型プログラミング』
関数型都市忘年会『はじめての函数型プログラミング』
Kenta USAMI
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2
Masao Kato
 
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
Takeshi Arabiki
 
Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Ra Zon
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2
Ransui Iso
 
Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Ra Zon
 
20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift
necocen
 
Introduction of Python
Introduction of PythonIntroduction of Python
Introduction of Python
Tomoya Nakayama
 
これからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツールこれからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツール
Nobuhisa Koizumi
 
20180728 halide-study
20180728 halide-study20180728 halide-study
20180728 halide-study
Fixstars Corporation
 
F#のすすめ
F#のすすめF#のすすめ
F#のすすめ
Hiromu Sasaki
 
Lisp batton - Common LISP
Lisp batton - Common LISPLisp batton - Common LISP
Lisp batton - Common LISPMasaomi CHIBA
 
手を動かしながら学ぶエンジニアのためのデータサイエンス!
手を動かしながら学ぶエンジニアのためのデータサイエンス!手を動かしながら学ぶエンジニアのためのデータサイエンス!
手を動かしながら学ぶエンジニアのためのデータサイエンス!
leverages_event
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
時響 逢坂
 
Material
MaterialMaterial
Material
_TUNE_
 
関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】
関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】
関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】
Tomoharu ASAMI
 

Similar to 関数プログラミング ことはじめ (再) (20)

たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
 
Rあんなときこんなとき(tokyo r#12)
Rあんなときこんなとき(tokyo r#12)Rあんなときこんなとき(tokyo r#12)
Rあんなときこんなとき(tokyo r#12)
 
関数型都市忘年会『はじめての函数型プログラミング』
関数型都市忘年会『はじめての函数型プログラミング』関数型都市忘年会『はじめての函数型プログラミング』
関数型都市忘年会『はじめての函数型プログラミング』
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2
 
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
 
Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2
 
Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]
 
20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift
 
Introduction of Python
Introduction of PythonIntroduction of Python
Introduction of Python
 
これからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツールこれからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツール
 
20180728 halide-study
20180728 halide-study20180728 halide-study
20180728 halide-study
 
F#のすすめ
F#のすすめF#のすすめ
F#のすすめ
 
Lisp batton - Common LISP
Lisp batton - Common LISPLisp batton - Common LISP
Lisp batton - Common LISP
 
手を動かしながら学ぶエンジニアのためのデータサイエンス!
手を動かしながら学ぶエンジニアのためのデータサイエンス!手を動かしながら学ぶエンジニアのためのデータサイエンス!
手を動かしながら学ぶエンジニアのためのデータサイエンス!
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
Material
MaterialMaterial
Material
 
関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】
関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】
関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】
 

関数プログラミング ことはじめ (再)