Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

(Ruby使いのための)Scalaで学ぶ関数型プログラミング

17,887 views

Published on

主にRuby使いを対象とした、Scalaによる関数型プログラミング入門です。

Published in: Technology, Education
  • Follow the link, new dating source: ❤❤❤ http://bit.ly/2u6xbL5 ❤❤❤
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Dating for everyone is here: ❶❶❶ http://bit.ly/2u6xbL5 ❶❶❶
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

(Ruby使いのための)Scalaで学ぶ関数型プログラミング

  1. 1. Ruby使いのための Scalaで学ぶ 関数型プログラミング Presented by おおかゆか
  2. 2. 自己紹介 おおかゆか (id: oukayuka) フリーランスのWebプログラマ。 元々はPHPerでしたが、最近はもっぱらRails案件を 生業に活動中。 Scalaに手を出したのは、ほんの3ヶ月ほど前。 エンジニアがお金について考えるためのrake:money という勉強会を主宰してます。月1の頻度で都内にて 開催しているので、興味があればどうぞ。 http://groups.google.co.jp/group/rakemoney
  3. 3. ≪注意≫ Scalaって何?という方は、これを読 む前にまず 「Ruby使いのための Scalaのススメ」 をご一読ください。 ☞http://ja.verbmode.net/2009/10/03/   recommend_of_scala_for_rubyist
  4. 4. よいRuby使いになるために Rubyは「acceptable Lisp」とか「MatzLisp」と 揶揄されることもあるくらい、Lispからの影響 が強い言語である。 Ruby使いがより一歩ステップアップするため にLispを学ぶべきとはよく言われるところ。 Eric Raymond も Paul Grahamも、ことあるご とにLispを薦めてくる。 しかしMatzも認めるように、Lispは普通の人 には扱いきれない習得コストの高い言語。
  5. 5. そこでScalaですよ それでもScalaなら…、Scalaならきっと何とかしてく れる。というのも、Scalaは最もRubyに似た関数型 言語だから。 Rubyと同じくALGOL系の文法を持つScalaは、関 数型言語のエッセンスを全て備えながら、Rubyと 同じく徹底したオブジェクト指向言語でもある。 Scalaこそが、Ruby使いが関数型プログラミングを 学ぶのに最も適した言語と言える。 Scalaを学べば、きっとよりよいRuby使いになれる はず…たぶん。
  6. 6. ➀ まずはScala の文法の基礎 から 魔法少女Scalaちゃん ©2009 熊ジェット
  7. 7. 1-1. 変数の定義 ≪使ったらある意味負け≫ ≪Scalaちゃん推奨≫ ■var(変数)型 ■val(値)型 var 変数名:型=値 val 変数名:型=値 例) 例) > var n: Int = 1 > val n: Int = 1 ☞n: Int = 1 ☞n: Int = 1 再代入できない! > n = 3 > n = 3 ☞n: Int = 3 ☞error: reassginment to val
  8. 8. 1-2. 代表的な型 数値 > val n: Int = 1 ☞n: Int = 1 文字列 > val str: String = ”hoge” ☞str: java.lang.String = hoge シンボル > val sym: Symbol = 'piyo ☞sym: Symbol = 'piyo リスト > val l: List[Int] = List(1,2,3) ☞l: List[Int] = List(1,2,3)
  9. 9. 1-3. 関数の定義 def 関数名(引数名:型, …):返り値の型 = { 処理内容 } 例) > def max(x: Int, y: Int): Int = { | if (x < y) y else x | } > max(8, 3) ☞res1: Int = 8
  10. 10. 1-4. 型推論 変数や関数の返り値の型宣言は、コンパイラ が推測できる限りにおいて省略できる! 省略 例) > val i = 4 ☞i: Int = 4 > val d = List(0.1, 1.2, 3.4) ☞d: List[Double] = List(0.1, 1.2, 3.4) > def hello = ”Hello, World!” ☞hello: java.lang.String
  11. 11. 1-5. 制御構文(1) - if if (条件文1) 値1 else if (条件文2) 値2 … else 値3 必ず値を返すことに注意! 例) > if (str.size < 3) { | ”It's short.” | } else if (str.size < 6) { | ”Not so long.” | } else ”It's long.” ☞res1: java.lang.String = It's long.
  12. 12. 1-6. 制御構文(2) - for for (ブロック引数 <- コレクション; …) 処理内容 for (ブロック引数 <- コレクション; …) yield 値 例) > for (i <- 1 to 9) print(i + ” ”) ☞1 2 3 4 5 6 7 8 9 > for (i <- (1 to 9).toList) yield i + 1 ☞res1: List[Int] = List(2,3,4,5,6,7,8,9,10) > for (i <- 1 to 2; j <- 1 to 3) print("[" + i + "," + j + "]") ☞[1,1][1,2][1,3][2,1][2,2][2,3]
  13. 13. ➁ 関数型プログラ ミングいくよー 魔法少女Scalaちゃん ©2009 熊ジェット
  14. 14. 2-1. 高階関数 Rubyのmapやsortメソッドのように、関数を引数に とる関数のこと。 例) > List(1,2,3).map(n => n + 1) ☞res1: List[Int] = List(2,3,4) > List(1,2,3,4,5).filter(n => n % 2 == 0) ☞res2: List[Int] = List(2, 4) 魔法の「_」(アンダーバー) > List(1,2,3,4).map(_ * 2) ☞res3: List[Int] = List(2,4,6,8)
  15. 15. 2-2. クロージャ Rubyのmapやsortメソッドのように、関数を引数に とる関数のこと。「無名関数」とも言う。 無名関数 (引数:型,…) => 値 例) > val sq = (n: Int) => Math.pow(n, 2).toInt > sq(6) ☞res1: Int = 36 > List(1,2,3,4,5).map(sq) ☞res2: List[Int] = List(1,4,9,16,25)
  16. 16. 2-3. 関数と変数は等価 例) > val half = (n: Int) => n / 2 ☞half: (Int) => Int = <function> > half(14) ☞res1: Int => 7 > def quartize(n: Int) = n / 4 > val quarter = quartize _ > quarter(20) ☞res1: Int => 5
  17. 17. 2-4. パターンマッチング(1) 引数 match { case パターン1 => 処理1 or 値1 : case _ => 処理x or 値x } 例) > val str = ”world” > str match { | case ”world” => println(”Hello!”) | case _ => () | } ☞Hello!
  18. 18. 2-5. パターンマッチング(2) 例) > List(1,2,3) match { | case List(a, b, c) => a + b + c | case _ => 0 } ☞res1: Int = 6 > val v: Any = ”hoge” > v match { | case i: Int => i * 100 | case s: String => s.size | } ☞res2: Int = 4
  19. 19. 2-6. 再帰関数 例) ループ型 > def sumLoop(n: Int) = { | var total = 0 | for (i <- 1 to n) total += i | total | } 再帰型 > def sumRecursive(n: Int): Int = n match { | case 1 => 1 返り値の型宣言 が必要! | case _ => n + sumRecursive(n - 1) | } > (sumLoop(10), sumRecursive(10)) ☞res1: (Int, Int) = (55,55)
  20. 20. 2-7. カリー化 複数の引数をとる関数を、引数が「元の関数の最初 の引数」で返り値が「元の関数の残りの引数をとり結 果を返す関数」であるような関数にすること。 例) > def multi(n: Int)(m: Int) = m * n > multi(6)(9) ☞res1: Int = 54 > def multiTwo = multi(2)_ > multiTwo(5) ☞res2: Int = 10
  21. 21. 2-8. 遅延評価 オブジェクトのフィールドの評価を、初期化時ではなく 参照時に行うようにする。 例) > class SchrodingerCat { | lazy val status = { | println("Here open a box..."); "alive!" | } | } > val cat = new SchrodingerCat > cat.status ☞Here open a box... ☞res1: java.lang.String = alive!
  22. 22. ➌ せめて、Ruby っ ぽ 第参最終章 く 魔法少女Scalaちゃん ©2009 熊ジェット
  23. 23. 3-1. Implicit Conversion Rubyはオープンクラスなので既存のクラスを自由に上書 きできる。しかしScalaは厳密な静的型付け言語のため同 じことはできない。しかし暗黙の型変換を使えば、その目 暗黙の型変換 的を達成できる場合が多い。 例) > class Cat > class Man { def greet = ”Hello!” } > implicit def cat2man(c: Cat): Man = new Man > val cat = new Cat > cat.greet ☞res1: java.lang.String = Hello!
  24. 24. 3-2. Structual Subtyping Scalaでダックタイピングっぽいことをやるための仕組み。 ダックタイピング 例) > class Cat > class Duck { | def swim = () | def quack = "Quaaa!" | } > def duckTest[T](x: T { def swim; def quack: String }) = "You're a duck!" > duckTest(new Duck) ☞res1: java.lang.String = You're a duck!
  25. 25. 以上です。 もっとScalaを詳しく 知りたくなった人は、 コップ本買ってね。 『Scalaスケーラブルプログラミング』 (通称:コップ本) 魔法少女Scalaちゃん ©2009 熊ジェット

×