Scala入門
関数型言語入門者がScalaの勉強会に参加したときの記録です。
自分の知識の再確認も含めて、これからScalaを始める方でも 読み進められるようにまとめていきます。
Scalaの魅力
2015年12月末日現在、Scalaは日本ではマイナーな言語かと思います。
大きな本屋に行ってもScalaの本は10冊も置いておらず、 1冊見つかれば御の字という寂しさです。
職業プログラマーを目指す上では、こうした案件の少なさそうな言語を 進んで習得する意味はあまりないかと存じます。
それではScalaを学習する意味とは何でしょうか。
ここではいくつかのScalaならではの魅力を紹介していきます。
map関数
たとえばJavaで、以下の様な配列を定義します。
int[] ary = {1, 2, 3, 4, 5};
そしてint型配列aryの各要素に対してインクリメントさせた、
int[] ary2 = {2, 3, 4, 5, 6};
という形の配列を得たいとします。
このときJavaではどのようなコードを書くでしょうか。一例を挙げると、
int[] ary = {1, 2, 3, 4, 5}; int[] ary2 = new int[5]; for (int i=0; i<5; i++) ary2[i] = ary[i]
というfor文を使ったコードになります。
これに対して、Scalaでは以下のように書けます。
val ary = Array(1, 2, 3, 4, 5) val ary2 = ary.map(_+1)
如何でしょうか。Scalaのmap関数は、配列(コレクション)の すべての要素に対し、引数の処理を適用します。
ですからデクリメントさせたい場合には
val ary = Array(1, 2, 3, 4, 5) val ary2 = ary.map(_-1)
このように書けばよいですし、またInt型配列からString型配列にキャストする場合には
val ary = Array(1, 2, 3, 4, 5) val ary2 = ary.map(_.toString)
と書けます。
このようにmap関数を用いることで、 配列のすべての要素に対する処理を極めて簡潔に表すことができます。
実に面倒がなくていいですね。楽です。素晴らしい。
この楽さこそがScalaのメリットです。
(本来は可読性とか副作用とか、そうした設計思想だったかと思いますが、まあ置いておきます。)
高階関数
さきほどのmap関数の実装について、疑問に思ったことがないでしょうか。
「どうして引数内に演算処理(+1, -1)やInt型のメンバ関数(.toString)を書いてよいのか」と。
これは関数型言語独特の、高階関数という概念です。
高階関数とは関数を引数や返り値として扱えるというもので、
これによってインクリメントやキャストという関数をmap関数の引数に取ることができる訳です。
関数すらも変数として扱うことで、手続き型やオブジェクト指向型よりも楽にコーディングできます。
パターンマッチング
単方向リストについて考えます。
単方向リストとは(データ、次のノードへの参照)というデータ構造を指します。
ここで単方向リストに対して線形探索を行うコードをScalaで書いてみましょう。
sealed trait List[+A] { def linearSearch[AA >: A](key: AA): Option[AA] = this match { case Node(h, t) => if (h==key) Some(h) else t.linearSearch(key) case Nothing => None } } case object Nothing extends List[Nothing] case class Node[+A](data: A, pointer: List[A]) extends List[A]
2行目から5行目でパターンマッチを行っています。
パターンマッチとはcase文の発展形で、上記の例だけでも以下の特徴を示しています。
- 関数の呼び出し元(this)に対して条件分岐を行える
- 型(クラス)によって分岐先を指定できる
- 分岐先でのみ使える一時的な変数(h, t)を束縛できる
実に多機能です。case文は可読性と排他性ぐらいしか利点がなく、
if文で代用できてしまうこともしばしばあります。
事実pythonなどではcase文は廃止され、if-else文を用いることになっていますね。
それに対しScalaのパターンマッチの何と強力なことでしょう。
case文だけでも一端のプログラムは書けるでしょうが、
パターンマッチを使うとコーディング量を大幅に減らすことができます。
(Javaで上のコードを書き直すと、一体何行になるのでしょうか。想像したくもありません。)
Scalaはシンプル
如何でしたか。Scalaは実に、無駄がなく気楽なコードを書くための機能を兼ね揃えています。
面倒なことが苦手な人ほど、Scalaを学習した方が捗るのではないでしょうか。
ぜひともScalaに挑戦してみてください。
Scala環境構築
『Functional Programing in Scala』読書録
勉強会に参加したときの記録です。
とはいえ、私はコンパイルを通すのに精一杯なので、 例題の関数の考察ばかり書いています。
こちらからご覧ください。
Scalaで『明解 Javaによるアルゴリズムとデータ構造』
表題通りScalaで『明解 Javaによるアルゴリズムとデータ構造』(以下、参考書) のサンプルコードを書き換えてみました。
Scalaは関数型言語であり、オブジェクト指向型や手続き型言語よりもアルゴリズムの 処理が得意なように見受けられます。
Javaで一度アルゴリズムを勉強なされた方がご覧になると、 関数型とオブジェクト指向型の違いや、Scalaという言語の特徴がわかりやすく 感じられることかと思います。
この項目は github上 にあるScalaに書き換えたコードのリファレンスを書いてゆきます。
ディレクトリ構成は参考書の章立てに準じています。
- 第1章:基本的なアルゴリズム
- 第2章:基本的なデータ構造
- 第3章:探索
- 第4章:スタックとキュー
- 第5章:再帰的アルゴリズム
- 第6章:ソート
- 第7章:集合
- 第8章:文字列探索
- 第9章:線形リスト
- 第10章:木構造
節の構成などにつきましては、参考書をご覧ください。
リファレンスへはこちらからどうぞ。