SlideShare a Scribd company logo
1 of 23
Download to read offline
15分でざっくり分かるScala入門
佐藤 祐一郎 JAIST IS 2014/6/21 kanazawa.rb meetup#22
1
自己紹介
2
 佐藤 祐一郎
 北陸先端科学技術大学院大学
情報科学研究科 博士後期2年
 人工知能作ってます
Scalaのいいところ
3
 JVM上で動く
(Javaのライブラリ
Java用のフレームワークなどに組み込める)
 オブジェクト指向+関数型
 きれいなJava
 個人的には困った時はJavaっぽく書けるし、Lispっぽくも
書けるし好き
Scala早見表 リテラル
4
Scala Java
Int int
Long long
Double double
Boolean boolean
String String
Tuple
Elem(xml)
その他Javaにあるものはある
val x : Int = 1
var str : String = “hoge”
val tuple = (1, “hoge”)
val xml = <xml><body>text</body></xml>
val 再代入不可
できるだけこっちを使う
var 再代入できる
できるだけ使わない
Scala早見表 制御構文
5
Scala Java
if (i < 10) { … } else { … } if (i < 10) { … } else { … }
while(i < 10){ … } while(i < 10) { … }
for(o : Object <- list) { … } for(Object o : list) { … }
n match {
case 1 => …
case 2 => …
case _ => …
}
switch(n) {
case 1 : … break;
case 2 : … break;
default : … break;
}
if文(式)は値を返す
val x = 1 + (if (true) 3 else 4)
->x : Int = 4
for文(式)も値を返せる
val list = for(i <- 1 to 10; if i % 3 == 0) yield i
->list = Vector(3,6,9)
Scala早見表 関数
6
Scala Java
def public
private def private
Unit void
return(省略可) return
コンパニオンオブジェクトで代用 static
override @Override
(arg0 : Type0, arg1 :Type1) => { … } (Type0 arg0, Type1 arg1) -> { … }
tlist : Type* Type… tlist
def inc(x : Int): Int = x + 1
private def positive(ls : List[Int]):List[Int] = {
ls foreach { print(_) }
ls filter (i => 0 < i)
}
Scala早見表 オブジェクト指向
7
Scala Java
class class
abstract abstract
trait(ただし実装を持てる!) interface
final final
extends extends
with implements
[A] <A>
[A <: B] A extends B
[A >: B] A super B
package package
import import
これくらい分かれば、ざっくりScalaは書ける
フィボナッチ数列
8
0, 1, 1, 2, 3, 5, 8, 13, …
0と1から始まって、あとは前の2つを足してできる数列
関数型プログラミングの入門でおなじみ
ヒマワリの種のつきかたとかが
フィボナッチ数列らしい
Javaっぽい実装
9
def fib(n : Int): BigInt = {
if (n <= 0) return 0
if (n == 1) return 1
var n1 = BigInt(0)
var result = BigInt(1)
for(i <- 2 to n) {
val tmp = result
result += n1
n1 = tmp
}
return result
}
これはn-1番目
これを
n番目
とすると
これはn-2番目
可読性 ?、 実行速度 ○
実行すると
for(i <- 0 to 100) print(fib(i)+",")
->0,1,1,2,3,5,8,13,21,34,55,…
関数型っぽい実装
10
def fib(n : Int): BigInt =
n match {
case n if n <= 0 => 0
case 1 => 1
case _ => fib(n - 1) + fib(n - 2)
}
fib(100) -> 終わらない
可読性 ◎、 実行速度 ×
nが0以下の場合ここにマッチ
nが0以下でも1でもないなら、前2つを足したもの
数学的な定義そのまま!
末尾再帰
11
def fib(n : Int): BigInt = {
if (n <= 0) return 0
def rec(i : Int, n1 : BigInt, result : BigInt):BigInt =
i match {
case i if n <= i => result
case _ => rec(i + 1, result, result + n1)
}
rec(1, 0, 1)
}
可読性 ○、 実行速度 ○
関数内で再帰関数を定義
カウンタ
ループを回りきったら即
計算結果を返す
関数に渡す前に計算しておく
varとかvalとかなくてもプログラムは書ける
オブジェクトプログラミング1
12
case class Person(val first_name : String,
middle_name : Option[String], last_name : String) {
def fullName: String =
middle_name match {
case Some(md : String) =>
first_name +" "+md+" "+last_name
case None => first_name+" "+last_name
}
def marryWith(person : Person): Person =
new Person(first_name, person.middle_name,
person.last_name)
}
Option型:nullの可能性がある値を包むモナド
caseクラス:equals()やhashCode()などを自動で作ってくれる
オブジェクトプログラミング2
13
object Person {
def apply(first_name : String, last_name : String): Person =
new Person(first_name, None, last_name)
def sasakiFamily(first_name : String): Person =
new Person(first_name, None, “Sasaki”)
}
val mika = Person.sasakiFamily(“Mika”)
コンパニオンオブジェクト:ここに定義された関数はstatic
ファクトリーみたいなもの
オブジェクトプログラミング3
14
val taro = Person.sasakiFamily("Taro")
val hana = Person("Hana", "Tanaka")
println(hana.fullName)
val sasaki_hana = hana marryWith taro
println(sasaki_hana.fullName)
->”Hana Tanaka”
“Hana Sasaki”
. とか () とか省略できる
15
Javaっぽく設計
関数型っぽく中身を実装
あとは
これでざっくりScala書ける
Javaには無い機能
16
クロージャ
17
def labelMaker(str : String): Unit => String = {
var i = 0
Unit => {
i += 1
str + i }}
val argMaker = labelMaker("arg")
for(i <- 1 to 3) print(argMaker()+",")
->arg1,arg2,arg3,
戻り値の型が関数
引数で与えられた文字列
クロージャ内に保存されている変数この
関数が
帰る
クロージャでフィボナッチ
18
def fib(n : Int): BigInt = {
val memo ={
var n1 = BigInt(1)
(x : BigInt) => {
var tmp = n1
n1 = x
tmp }}
var result = BigInt(0)
for(i <- 1 to n) result += memo(result)
result
}
引数で与えられた数を保存し、
前回保存した数を返す関数
関数の部分適用
19
def sandwich
(header : String)(fooder : String)(body : String): String =
header + body + fooder
def htmlMaker(tag : String)(body : String): String =
sandwich("<" + tag + ">")("</" + tag + ">")(body)
val commentout = sandwich("<!-- ")(" -->")_
val ptag = htmlMaker("p")_
println(commentout(“here is a text "))
List("hoge","goo","foo") map ptag foreach print
-><!– here is a text -->
<p>hoge</p><p>goo</p><p>foo</p>
3つ目の引数はまだ与えない
後から3つ目の引数を与える
何度でも使える
引数のカッコを区切る
部分適用でフィボナッチ
20
def fib(n : Int): BigInt = {
def add(n1 : BigInt)(n2 : BigInt): BigInt = n1 + n2
def rec(i : Int, add_memo : BigInt => BigInt,
result : BigInt): BigInt =
i match {
case i if n <= i => result
case _ => rec(i+1, add(result), add_memo(result))
}
rec(0, add(BigInt(1)), BigInt(0))
}
個人的にはこれが一番かな?
数をとってresultを足す関数
覚えていた数にresultを足す
暗黙の型変換
21
class ExtString(val str: String) {
def -(str2 : ExtString): ExtString = new ExtString(str.replace(str2.str, ""))
def *(str2 : String): List[String] =
for(s <- this.allSubstring; t <- new ExtString(str2).allSubstring)
yield s + t
def allSubstring: List[String] = { … }
override def toString(): String = str
}
object ExtString {
implicit def string2ExtString(str : String) = new ExtString(str)
}
import ExtString._
println("hoge" - "og")
"wnzk" * "a" filter(_.length == 2) foreach {print(_)}
->”he”
“ka””na””za””wa”
リテラルを自由に拡張できる!
Stringには – や * など無い
ExtStringにはあるから、
StringからExtStringへ変換する
変換規則を定義しておけばいい
文字列の全通りの組
無限リストでフィボナッチ
22
lazy val fib: Stream[BigInt] =
Stream.cons(0,
Stream.cons(1, fib.zip(fib.tail).map(p => p._1 + p._2)))
(0,1,1,2,3,5,8,…
無限リスト
(1,1,2,3,5,8,…
((0,1),(1,1),(1,2),(2,3),(3,5),(5,8),…
zip
タプルの要素を足す
(1,2,3,5,8,13… フィボナッチ数列
ちなみに ベンチマーク
23
1,000 10,000 100,000 500,000
Javaっぽい 5 20 223 4415
末尾再帰 3 4 182 4501
クロージャ 4 8 186 4401
部分適用 2 6 187 4703
無限リスト 28 69 OutOfMemoryError OutOfMemoryError
-Xmx 1024 -Xms 1024 でfib(n)を計算するのにかかる時間(ミリ秒)

More Related Content

What's hot

これから Haskell を書くにあたって
これから Haskell を書くにあたってこれから Haskell を書くにあたって
これから Haskell を書くにあたってTsuyoshi Matsudate
 
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるHideyuki Tanaka
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Ransui Iso
 
これからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツールこれからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツールNobuhisa Koizumi
 
Java SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイルJava SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイルなおき きしだ
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Ransui Iso
 
純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門Kimikazu Kato
 
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミングOuka Yuka
 
constexpr idioms
constexpr idiomsconstexpr idioms
constexpr idiomsfimbul
 
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けープログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けーTanUkkii
 
Frege, What a Non-strict Language
Frege, What a Non-strict LanguageFrege, What a Non-strict Language
Frege, What a Non-strict Languagey_taka_23
 
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜Hiromi Ishii
 
Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Naoki Aoyama
 
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarrayRyosuke839
 
【java8 勉強会】 怖くない!ラムダ式, Stream API
【java8 勉強会】 怖くない!ラムダ式, Stream API【java8 勉強会】 怖くない!ラムダ式, Stream API
【java8 勉強会】 怖くない!ラムダ式, Stream APIdcomsolution
 
中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexprGenya Murakami
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdfHiroshi Ono
 

What's hot (19)

これから Haskell を書くにあたって
これから Haskell を書くにあたってこれから Haskell を書くにあたって
これから Haskell を書くにあたって
 
Thinking in Cats
Thinking in CatsThinking in Cats
Thinking in Cats
 
Haskell超入門 Part.1
Haskell超入門 Part.1Haskell超入門 Part.1
Haskell超入門 Part.1
 
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISる
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2
 
これからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツールこれからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツール
 
Java SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイルJava SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイル
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3
 
純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門
 
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
 
constexpr idioms
constexpr idiomsconstexpr idioms
constexpr idioms
 
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けープログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
 
Frege, What a Non-strict Language
Frege, What a Non-strict LanguageFrege, What a Non-strict Language
Frege, What a Non-strict Language
 
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
 
Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術
 
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray
 
【java8 勉強会】 怖くない!ラムダ式, Stream API
【java8 勉強会】 怖くない!ラムダ式, Stream API【java8 勉強会】 怖くない!ラムダ式, Stream API
【java8 勉強会】 怖くない!ラムダ式, Stream API
 
中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexpr
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 

Similar to 15分でざっくり分かるScala入門

関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)啓 小笠原
 
第3回 JavaScriptから始めるプログラミング2016
第3回 JavaScriptから始めるプログラミング2016第3回 JavaScriptから始めるプログラミング2016
第3回 JavaScriptから始めるプログラミング2016kyoto university
 
Incanterの紹介
Incanterの紹介Incanterの紹介
Incanterの紹介mozk_
 
Pythonで始めるDropboxAPI
Pythonで始めるDropboxAPIPythonで始めるDropboxAPI
Pythonで始めるDropboxAPIDaisuke Igarashi
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2Masao Kato
 
Kashiwa.R#1 画像解析とパターン認識における R の利用
Kashiwa.R#1 画像解析とパターン認識における R の利用Kashiwa.R#1 画像解析とパターン認識における R の利用
Kashiwa.R#1 画像解析とパターン認識における R の利用nmaro
 
Java電卓勉強会資料
Java電卓勉強会資料Java電卓勉強会資料
Java電卓勉強会資料Toshio Ehara
 
ディープニューラルネット入門
ディープニューラルネット入門ディープニューラルネット入門
ディープニューラルネット入門TanUkkii
 
Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016Yoshio Terada
 
Enjoy handwritten digits recognition AI !!
Enjoy handwritten digits recognition AI !!Enjoy handwritten digits recognition AI !!
Enjoy handwritten digits recognition AI !!KAIKenzo
 
Xtend - Javaの未来を今すぐ使う
Xtend - Javaの未来を今すぐ使うXtend - Javaの未来を今すぐ使う
Xtend - Javaの未来を今すぐ使うTatsumi Naganuma
 
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Springanyakichi
 
[機械学習]文章のクラス分類
[機械学習]文章のクラス分類[機械学習]文章のクラス分類
[機械学習]文章のクラス分類Tetsuya Hasegawa
 
Synthesijer and Synthesijer.Scala in HLS-friends 201512
Synthesijer and Synthesijer.Scala in HLS-friends 201512Synthesijer and Synthesijer.Scala in HLS-friends 201512
Synthesijer and Synthesijer.Scala in HLS-friends 201512Takefumi MIYOSHI
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdfHiroshi Ono
 

Similar to 15分でざっくり分かるScala入門 (20)

Introduction of Python
Introduction of PythonIntroduction of Python
Introduction of Python
 
ATN No.2 Scala事始め
ATN No.2 Scala事始めATN No.2 Scala事始め
ATN No.2 Scala事始め
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
Rの高速化
Rの高速化Rの高速化
Rの高速化
 
第3回 JavaScriptから始めるプログラミング2016
第3回 JavaScriptから始めるプログラミング2016第3回 JavaScriptから始めるプログラミング2016
第3回 JavaScriptから始めるプログラミング2016
 
Incanterの紹介
Incanterの紹介Incanterの紹介
Incanterの紹介
 
Pythonで始めるDropboxAPI
Pythonで始めるDropboxAPIPythonで始めるDropboxAPI
Pythonで始めるDropboxAPI
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2
 
Kashiwa.R#1 画像解析とパターン認識における R の利用
Kashiwa.R#1 画像解析とパターン認識における R の利用Kashiwa.R#1 画像解析とパターン認識における R の利用
Kashiwa.R#1 画像解析とパターン認識における R の利用
 
R intro
R introR intro
R intro
 
Java電卓勉強会資料
Java電卓勉強会資料Java電卓勉強会資料
Java電卓勉強会資料
 
ディープニューラルネット入門
ディープニューラルネット入門ディープニューラルネット入門
ディープニューラルネット入門
 
Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016
 
ji-6. 配列
ji-6. 配列ji-6. 配列
ji-6. 配列
 
Enjoy handwritten digits recognition AI !!
Enjoy handwritten digits recognition AI !!Enjoy handwritten digits recognition AI !!
Enjoy handwritten digits recognition AI !!
 
Xtend - Javaの未来を今すぐ使う
Xtend - Javaの未来を今すぐ使うXtend - Javaの未来を今すぐ使う
Xtend - Javaの未来を今すぐ使う
 
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Spring
 
[機械学習]文章のクラス分類
[機械学習]文章のクラス分類[機械学習]文章のクラス分類
[機械学習]文章のクラス分類
 
Synthesijer and Synthesijer.Scala in HLS-friends 201512
Synthesijer and Synthesijer.Scala in HLS-friends 201512Synthesijer and Synthesijer.Scala in HLS-friends 201512
Synthesijer and Synthesijer.Scala in HLS-friends 201512
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 

15分でざっくり分かるScala入門

  • 2. 自己紹介 2  佐藤 祐一郎  北陸先端科学技術大学院大学 情報科学研究科 博士後期2年  人工知能作ってます
  • 3. Scalaのいいところ 3  JVM上で動く (Javaのライブラリ Java用のフレームワークなどに組み込める)  オブジェクト指向+関数型  きれいなJava  個人的には困った時はJavaっぽく書けるし、Lispっぽくも 書けるし好き
  • 4. Scala早見表 リテラル 4 Scala Java Int int Long long Double double Boolean boolean String String Tuple Elem(xml) その他Javaにあるものはある val x : Int = 1 var str : String = “hoge” val tuple = (1, “hoge”) val xml = <xml><body>text</body></xml> val 再代入不可 できるだけこっちを使う var 再代入できる できるだけ使わない
  • 5. Scala早見表 制御構文 5 Scala Java if (i < 10) { … } else { … } if (i < 10) { … } else { … } while(i < 10){ … } while(i < 10) { … } for(o : Object <- list) { … } for(Object o : list) { … } n match { case 1 => … case 2 => … case _ => … } switch(n) { case 1 : … break; case 2 : … break; default : … break; } if文(式)は値を返す val x = 1 + (if (true) 3 else 4) ->x : Int = 4 for文(式)も値を返せる val list = for(i <- 1 to 10; if i % 3 == 0) yield i ->list = Vector(3,6,9)
  • 6. Scala早見表 関数 6 Scala Java def public private def private Unit void return(省略可) return コンパニオンオブジェクトで代用 static override @Override (arg0 : Type0, arg1 :Type1) => { … } (Type0 arg0, Type1 arg1) -> { … } tlist : Type* Type… tlist def inc(x : Int): Int = x + 1 private def positive(ls : List[Int]):List[Int] = { ls foreach { print(_) } ls filter (i => 0 < i) }
  • 7. Scala早見表 オブジェクト指向 7 Scala Java class class abstract abstract trait(ただし実装を持てる!) interface final final extends extends with implements [A] <A> [A <: B] A extends B [A >: B] A super B package package import import これくらい分かれば、ざっくりScalaは書ける
  • 8. フィボナッチ数列 8 0, 1, 1, 2, 3, 5, 8, 13, … 0と1から始まって、あとは前の2つを足してできる数列 関数型プログラミングの入門でおなじみ ヒマワリの種のつきかたとかが フィボナッチ数列らしい
  • 9. Javaっぽい実装 9 def fib(n : Int): BigInt = { if (n <= 0) return 0 if (n == 1) return 1 var n1 = BigInt(0) var result = BigInt(1) for(i <- 2 to n) { val tmp = result result += n1 n1 = tmp } return result } これはn-1番目 これを n番目 とすると これはn-2番目 可読性 ?、 実行速度 ○ 実行すると for(i <- 0 to 100) print(fib(i)+",") ->0,1,1,2,3,5,8,13,21,34,55,…
  • 10. 関数型っぽい実装 10 def fib(n : Int): BigInt = n match { case n if n <= 0 => 0 case 1 => 1 case _ => fib(n - 1) + fib(n - 2) } fib(100) -> 終わらない 可読性 ◎、 実行速度 × nが0以下の場合ここにマッチ nが0以下でも1でもないなら、前2つを足したもの 数学的な定義そのまま!
  • 11. 末尾再帰 11 def fib(n : Int): BigInt = { if (n <= 0) return 0 def rec(i : Int, n1 : BigInt, result : BigInt):BigInt = i match { case i if n <= i => result case _ => rec(i + 1, result, result + n1) } rec(1, 0, 1) } 可読性 ○、 実行速度 ○ 関数内で再帰関数を定義 カウンタ ループを回りきったら即 計算結果を返す 関数に渡す前に計算しておく varとかvalとかなくてもプログラムは書ける
  • 12. オブジェクトプログラミング1 12 case class Person(val first_name : String, middle_name : Option[String], last_name : String) { def fullName: String = middle_name match { case Some(md : String) => first_name +" "+md+" "+last_name case None => first_name+" "+last_name } def marryWith(person : Person): Person = new Person(first_name, person.middle_name, person.last_name) } Option型:nullの可能性がある値を包むモナド caseクラス:equals()やhashCode()などを自動で作ってくれる
  • 13. オブジェクトプログラミング2 13 object Person { def apply(first_name : String, last_name : String): Person = new Person(first_name, None, last_name) def sasakiFamily(first_name : String): Person = new Person(first_name, None, “Sasaki”) } val mika = Person.sasakiFamily(“Mika”) コンパニオンオブジェクト:ここに定義された関数はstatic ファクトリーみたいなもの
  • 14. オブジェクトプログラミング3 14 val taro = Person.sasakiFamily("Taro") val hana = Person("Hana", "Tanaka") println(hana.fullName) val sasaki_hana = hana marryWith taro println(sasaki_hana.fullName) ->”Hana Tanaka” “Hana Sasaki” . とか () とか省略できる
  • 17. クロージャ 17 def labelMaker(str : String): Unit => String = { var i = 0 Unit => { i += 1 str + i }} val argMaker = labelMaker("arg") for(i <- 1 to 3) print(argMaker()+",") ->arg1,arg2,arg3, 戻り値の型が関数 引数で与えられた文字列 クロージャ内に保存されている変数この 関数が 帰る
  • 18. クロージャでフィボナッチ 18 def fib(n : Int): BigInt = { val memo ={ var n1 = BigInt(1) (x : BigInt) => { var tmp = n1 n1 = x tmp }} var result = BigInt(0) for(i <- 1 to n) result += memo(result) result } 引数で与えられた数を保存し、 前回保存した数を返す関数
  • 19. 関数の部分適用 19 def sandwich (header : String)(fooder : String)(body : String): String = header + body + fooder def htmlMaker(tag : String)(body : String): String = sandwich("<" + tag + ">")("</" + tag + ">")(body) val commentout = sandwich("<!-- ")(" -->")_ val ptag = htmlMaker("p")_ println(commentout(“here is a text ")) List("hoge","goo","foo") map ptag foreach print -><!– here is a text --> <p>hoge</p><p>goo</p><p>foo</p> 3つ目の引数はまだ与えない 後から3つ目の引数を与える 何度でも使える 引数のカッコを区切る
  • 20. 部分適用でフィボナッチ 20 def fib(n : Int): BigInt = { def add(n1 : BigInt)(n2 : BigInt): BigInt = n1 + n2 def rec(i : Int, add_memo : BigInt => BigInt, result : BigInt): BigInt = i match { case i if n <= i => result case _ => rec(i+1, add(result), add_memo(result)) } rec(0, add(BigInt(1)), BigInt(0)) } 個人的にはこれが一番かな? 数をとってresultを足す関数 覚えていた数にresultを足す
  • 21. 暗黙の型変換 21 class ExtString(val str: String) { def -(str2 : ExtString): ExtString = new ExtString(str.replace(str2.str, "")) def *(str2 : String): List[String] = for(s <- this.allSubstring; t <- new ExtString(str2).allSubstring) yield s + t def allSubstring: List[String] = { … } override def toString(): String = str } object ExtString { implicit def string2ExtString(str : String) = new ExtString(str) } import ExtString._ println("hoge" - "og") "wnzk" * "a" filter(_.length == 2) foreach {print(_)} ->”he” “ka””na””za””wa” リテラルを自由に拡張できる! Stringには – や * など無い ExtStringにはあるから、 StringからExtStringへ変換する 変換規則を定義しておけばいい 文字列の全通りの組
  • 22. 無限リストでフィボナッチ 22 lazy val fib: Stream[BigInt] = Stream.cons(0, Stream.cons(1, fib.zip(fib.tail).map(p => p._1 + p._2))) (0,1,1,2,3,5,8,… 無限リスト (1,1,2,3,5,8,… ((0,1),(1,1),(1,2),(2,3),(3,5),(5,8),… zip タプルの要素を足す (1,2,3,5,8,13… フィボナッチ数列
  • 23. ちなみに ベンチマーク 23 1,000 10,000 100,000 500,000 Javaっぽい 5 20 223 4415 末尾再帰 3 4 182 4501 クロージャ 4 8 186 4401 部分適用 2 6 187 4703 無限リスト 28 69 OutOfMemoryError OutOfMemoryError -Xmx 1024 -Xms 1024 でfib(n)を計算するのにかかる時間(ミリ秒)