Successfully reported this slideshow.
Your SlideShare is downloading. ×

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

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 23 Ad
Advertisement

More Related Content

Slideshows for you (19)

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

Advertisement

Recently uploaded (20)

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

  1. 1. 15分でざっくり分かるScala入門 佐藤 祐一郎 JAIST IS 2014/6/21 kanazawa.rb meetup#22 1
  2. 2. 自己紹介 2  佐藤 祐一郎  北陸先端科学技術大学院大学 情報科学研究科 博士後期2年  人工知能作ってます
  3. 3. Scalaのいいところ 3  JVM上で動く (Javaのライブラリ Java用のフレームワークなどに組み込める)  オブジェクト指向+関数型  きれいなJava  個人的には困った時はJavaっぽく書けるし、Lispっぽくも 書けるし好き
  4. 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. 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. 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. 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. フィボナッチ数列 8 0, 1, 1, 2, 3, 5, 8, 13, … 0と1から始まって、あとは前の2つを足してできる数列 関数型プログラミングの入門でおなじみ ヒマワリの種のつきかたとかが フィボナッチ数列らしい
  9. 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. 関数型っぽい実装 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. 末尾再帰 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. 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. 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. 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” . とか () とか省略できる
  15. 15. 15 Javaっぽく設計 関数型っぽく中身を実装 あとは これでざっくりScala書ける
  16. 16. Javaには無い機能 16
  17. 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. クロージャでフィボナッチ 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. 関数の部分適用 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. 部分適用でフィボナッチ 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. 暗黙の型変換 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. 無限リストでフィボナッチ 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. ちなみに ベンチマーク 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)を計算するのにかかる時間(ミリ秒)

×