Recommended
PDF
オブジェクト指向開発におけるObject-Functional Programming
PDF
Object-Functional Analysis and Design and Programming温泉
PDF
Monadic Programmingのススメ - Functional Reactive Programmingへのアプローチ
PDF
Scalaz-StreamによるFunctional Reactive Programming
PDF
PDF
Object-Funcational Analysis and design
PDF
Object-Functional Analysis and Design : 次世代モデリングパラダイムへの道標
PDF
PDF
協調モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第7回】
PDF
PDF
PDF
PDF
KEY
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
PDF
PDF
PDF
PDF
なぜリアクティブは重要か #ScalaMatsuri
PPTX
PDF
PDF
PDF
KEY
Algebraic DP: 動的計画法を書きやすく
PDF
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
PDF
PDF
PDF
あなたのScalaを爆速にする7つの方法(日本語版)
PDF
PDF
PDF
More Related Content
PDF
オブジェクト指向開発におけるObject-Functional Programming
PDF
Object-Functional Analysis and Design and Programming温泉
PDF
Monadic Programmingのススメ - Functional Reactive Programmingへのアプローチ
PDF
Scalaz-StreamによるFunctional Reactive Programming
PDF
PDF
Object-Funcational Analysis and design
PDF
Object-Functional Analysis and Design : 次世代モデリングパラダイムへの道標
PDF
What's hot
PDF
協調モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第7回】
PDF
PDF
PDF
PDF
KEY
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
PDF
PDF
PDF
PDF
なぜリアクティブは重要か #ScalaMatsuri
PPTX
PDF
PDF
PDF
KEY
Algebraic DP: 動的計画法を書きやすく
PDF
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
PDF
PDF
PDF
あなたのScalaを爆速にする7つの方法(日本語版)
PDF
Viewers also liked
PDF
PDF
PDF
PPTX
Terraformでオーケストレーションを統一する
PPTX
Prefer Cloud Platform - ビジョン、アーキテクチャ
PDF
2014 akka-streams-tokyo-japanese
PPTX
Scala Refactoring for Fun and Profit (Japanese subtitles)
PDF
Similar to Scalaプログラミング・マニアックス
PDF
PDF
PDF
PDF
PDF
PDF
関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】
PDF
PDF
PDF
PDF
PDF
Scala の関数型プログラミングを支える技術
PDF
PDF
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
PPTX
PDF
関数型言語テイスティング: Haskell, Scala, Clojure, Elixirを比べて味わう関数型プログラミングの旨さ
PDF
PDF
ODP
PPTX
PDF
命令プログラミングから関数プログラミングへ
More from Tomoharu ASAMI
PDF
AI時代のソフトウェア開発 文芸モデル駆動アプローチ : 文芸モデルをDSLとした文芸モデル開発と生成AI連携の知識ベース
PDF
ケーススタディ/テスト 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第47回】
PDF
ケーススタディ/実装 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第46回】
PDF
設計モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第45回】
PDF
分析モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第44回】
PDF
要求モデル/BDD 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第43回】
PDF
要求モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第42回】
PDF
ビジネス・モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第41回】
PDF
ケーススタディ 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第40回】
PDF
Cloud Native Component Framework 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第39回】
PDF
プレゼンテーション・サブシステム 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第38回】
PDF
アプリケーション・サブシステム 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第37回】
PDF
ドメイン・サブシステム 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第36回】
PDF
Cloud Native CBD 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第35回】
PDF
アプリケーション・アーキテクチャ 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第34回】
PDF
テスト 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第33回】
PDF
実装(3) 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第32回】
PDF
実装(2) 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第31回】
PDF
実装(1) 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第30回】
PDF
設計/UX/UI 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第29回】
Scalaプログラミング・マニアックス 1. 2. 3. 関連サイト
• Modegramming Style (テキストDSL駆動開発を
テーマにしたブログ)
• http://modegramming.blogspot.com/
• SimpleModeler
• http://github.com/asami/simplemodeler/
• SmartDox
• http://github.com/asami/smartdox
• g3フレームワーク
• http://code.google.com/p/goldenport3/
• g4フレームワーク
• http://github.com/asami/goldenport-android-
library/
4. 5. 6. 諸元
• スライド
• Scala 2.9.2
• Scalaz 6.0.4
• 最新
• Scala 2.10.0 M6
• Scalaz 7 開発中 (2012年年4⽉月リリース予定?)
• Scala 2.10で並列列プログラミング周りが⼤大幅に変更更され
る予定
• Akka(Actor)、STM、Future/Promise
• Scala 2.10 + Scalaz7で新しいバランスになるので、⾒見見極
めが必要
7. 8. アプリケーションの階層と役割
アプリケー • DSLの作法に従ってビジネスロ
ジックを記述
ション • OO、関数型のスキルは最低限
• フレームワークを簡単に使⽤用する
DSL ための専⽤用⾔言語
• OO、関数型の⾼高度度なスキル
フレーム • ドメインの共通処理理を記述
ワーク • OO、関数型の⾼高度度なスキル
9. 10. 11. 12. 関数型⾔言語の⻑⾧長所と短所
⻑⾧長所
• ⾼高階関数を使った技が使える
• List処理理, 関数合成(コンビネータ)、モナドなど
• 定理理と証明
• 証明された(動作保証された)定理理(関数)を積み上げてプログラムを
記述できる (← 多少理理想論論も⼊入ってます)
短所
• 関数実⾏行行のオーバーヘッド
• 関数オブジェクト
• メモリを⼤大量量に消費する
• 関数オブジェクト
• データの⼤大量量複写
• スタックの使⽤用量量が読めない
• 再帰
• 回避する技のノウハウが必要
13. 14. 代数的データ型
• Algebraic data type
• 直積の直和の総和
• 再帰構造
ケースクラスで直積を実現
case class Person(name: String, age: Int)
Case class Company(name: String, phone: String)
Eitherで直積の直和を実現
Either[Person, Company]
sealedトレイトで直積の直和の総和を実現
sealed trait Party
case class Person(name: String, age: Int) extends Party
case class Company(name: String, phone: String) extends Party
15. 永続データ構造
• Persistent data structure
• 変更更される際に変更更前のバージョンを常に保持するデータ構造で
ある。このようなデータ構造は、更更新の際に元のデータ構造を書
き換えるのではなく、新たなデータ構造を⽣生成すると考えられ、
イミュータブルなデータ構造の構築に利利⽤用可能である(Wikipedia)
16. 代数的構造デザインパターン
結合律律 (associative law)
• 半群 (semigroup)
• モノイド (monoid) (a + b) + c = a + (b + c)
• 群 (group)
可換律律 (commutative law)
• 可換半群
• 可換モノイド a+b=b+a
• 可換群(アーベル群)
分配律律 (distributive law)
• 環 (ring)
• 体 (field) a * (b + c) = a * b + a * c
17. 圏論論デザインパターン
圏 (category)
モナド • Hask圏 (Scala圏?)
(monad) • クライスリ圏
(kleisli category)
Applicative 射 (arrow,
functor morphism)
関⼿手
(functor)
18. 型クラス
• 3つのポリモーフィズム
• サブタイプ・ポリモーフィズム
• OOのポリモーフィズム
• パラメタ・ポリモーフィズム
• ジェネリックタイプ
• アドホック・ポリモーフィズム
• 浅海の理理解
• アドホック・ポリモーフィズムを使って、サブタイプ・ポリ
モーフィズム的なことを型の決定時に⾏行行う
• 関数型⾔言語でオブジェクト指向のサブタイプ・ポリモーフィズ
ム的なことができる
• ただし、コンパイル時に型が確定するのがOOとの違い
• 型クラスを使うと、呼び出し元と呼び出し先と呼ばれる関数
を疎結合にできる
• システムの拡張性
• 主な使⽤用例例:代数的構造を既存のデータ構造に適⽤用する
19. 並列列プログラミング
• マルチスレッド
• 共有状態 (shared mutability)
• 共有状態をロック ← 伝統的⽅方法
• STM (Software Transactional Memory)
• アクター
• 状態をアクターローカル(スレッドローカル)にする (isolating
mutability)
• 不不変オブジェクトによるメッセージで通信
• 関数プログラミング⽅方式
• 代数的データ型、永続データ構造
• ⇒ 不不変オブジェクト
• 状態変更更ではなく、状態変更更命令令書を計算
• イメージとしてはSQLの⽂文字列列を計算して作成する感じ
• モナドのメカニズムを使って並列列処理理(+状態変更更命令令書)を
隠蔽
20. Monadicプログラミングの効⽤用
Java⾵風
def validate(name: String, age: Int): ValidationNEL[Throwable, (String,
Int)] = {!
val a = validateName(name) !
val b = validateAge(age) !
if (a.isSuccess && b.isSuccess) { !
val a1 = a.asInstanceOf[Success[NonEmptyList[Throwable], String]].a !
val b1 = b.asInstanceOf[Success[NonEmptyList[Throwable], Int]].a !
Success((a1, b1)) !
} else if (a.isSuccess) { !
b.asInstanceOf[Failure[NonEmptyList[Throwable], (String, Int)]] !
} else if (b.isSuccess) { !
a.asInstanceOf[Failure[NonEmptyList[Throwable], (String, Int)]] !
} else { !
val a1 = a.asInstanceOf[Failure[NonEmptyList[Throwable], String]].e !
val b1 = b.asInstanceOf[Failure[NonEmptyList[Throwable], Int]].e !
Failure(a1 |+| b1) !
} !
}!
21. Scala (関数型プログラミング)
def validate(name: String, age: Int):
ValidationNEL[Throwable, (String, Int)] = { !
validateName(name) match { !
case Success(a) => validateAge(age) match { !
case Success(b) => Success((a, b)) !
case Failure(e) => Failure(e) !
} !
case Failure(e1) => validateAge(age) match { !
case Success(b) => Failure(e1) !
case Failure(e2) => Failure(e1 |+| e2) !
} !
} !
} !
Scalaz (Monadicプログラミング)
def validate(name: String, age: Int):
ValidationNEL[Throwable, (String, Int)] = { !
(validateName(name) ⊛ validateAge(age))((_, _)) !
}!
URL: http://modegramming.blogspot.jp/2012/04/
scala-tips-validation-10-applicative.html
22. トピックス
• Monad
• http://modegramming.blogspot.jp/2012/08/30-13-
monad.html
• Monoid
• http://modegramming.blogspot.jp/2012/08/30-12-
monoid.html
• Fold
• http://modegramming.blogspot.jp/2012/07/30-10-
map-filter-fold.html
23. 24. 25. パイプラインの構成部品
メソッド メソッド動作 動作イメージ コンテナ型 要素型 要素数
map コンテナ内の要素に M[A]→M[B] 変わらない 変わる 同じ
関数を適⽤用して新し
いコンテナに詰め直
す。
filter コンテナ内の要素を M[A]→M[A] 変わらない 変わらない 同じ/減る
選別して新しコンテ
ナに詰め直す。
fold コンテナをまるごと M[A]→N 変わる N/A N/A
別のオブジェクトに
変換する。
reduce コンテナの内容を⼀一 M[A]→A 変わる N/A N/A
つにまとめる。
collect コンテナ内の要素に M[A]→M[B] 変わらない 変わる 同じ/減る
部分関数を適⽤用して
選択と変換を⾏行行う。
flatMap コンテナ内の要素ご M[A]→M[B] 変わらない 変わる 同じ/増える/減
とにコンテナを作成 る
する関数を適⽤用し最
後に⼀一つのコンテナ
にまとめる。
26. 27. 28. OFP新三種の神器
トレイト (trait)
• mix-in
• 型安全のAOP的な運⽤用
モナド (monad)
• 計算⽂文脈をカプセル化する新しい⾔言語概念念
• Monadicプログラミング
型クラス (type class)
• 型安全のダブルディスパッチ(?)
• Scalaでは、⽂文脈、主体、客体の組でオブジェクトを束縛
29. トレイト
• mixinのためのクラス的なもの
• クラスの継承に制限をつけることで、多重継承的なこと
ができるようになる
• Scalaプログラミングの要
• Cakeパターン
• モジュール化
• 型安全Dependency Injection
• http://www.crosson.org/2012/03/dependency-
injection-using-scala-traits.html
• http://www.warski.org/blog/2010/12/di-in-scala-cake-
pattern/
• http://jonasboner.com/2008/10/06/real-world-scala-
dependency-injection-di/
30. 31. 32. 33. DSLの例:SparkとScalding
val file = spark.textFile("hdfs://...")
file.flatMap(line => line.split(" "))
.map(word => (word, 1))
Spark
.reduceByKey(_ + _)
class WordCountJob(args : Args) extends Job(args) {
TextLine( args("input") ).read.
flatMap('line -> 'word) { line : String => line.split("s+") }.
groupBy('word) { _.size }.
write( Tsv( args("output") ) )
}
Scalding
• https://github.com/twitter/scalding
• CascadingのScala DSL
• Collection APIでHadoop演算
34. 35. Monadicプログラミングで
やりたいこと
• 定義
• 普通
• Monadを使ったプログラミング。
• 本セッションでの広い意味
• Monadを中⼼心としつつも、旧来からあるFunctorによるプログ
ラミング、関数合成、コンビネータなども包含しつつ、パイプ
ライン・プログラミングのスタイルとしてまとめたもの。
• やりたいこと
• 楽々プログラミング
• 並列列プログラミング
• DSL
36. 楽々プログラミング
def main(args: Array[String]) {
records |> build部⾨門 >>> buildTree >>> showTree
}
def build部⾨門(records: Seq[Map[Symbol, Any]]): Map[Int, 部⾨門] = {
records.foldRight(Map[Int, 部⾨門]())((x, a) => {
val 部⾨門ID = x('部⾨門ID).asInstanceOf[Int]
val 部⾨門名 = x('部⾨門名).asInstanceOf[String]
val 親部⾨門ID = x('親部⾨門ID).asInstanceOf[Option[Int]]
val 親部⾨門名 = x.get('親部⾨門名).asInstanceOf[Option[String]]
a + (部⾨門ID -> 部⾨門(部⾨門ID, 部⾨門名, 親部⾨門ID, 親部⾨門名))
})
}
def buildTree(sections: Map[Int, 部⾨門]): Tree[部⾨門] = {
def build(sec: 部⾨門): Tree[部⾨門] = {
val children = sections collect {
case (k, v) if v.親部⾨門ID == sec.部⾨門ID.some => v
}
node(sec, children.toStream.sortBy(_.部⾨門ID).map(build))
}
build(sections(1))
}
def showTree(tree: Tree[部⾨門]) {
println(tree.drawTree(showA[部⾨門]))
}
37. val records = List(Map('部⾨門ID -> 1,
'部⾨門名 -> "営業統括", Map('部⾨門ID -> 121,
'親部⾨門ID -> None, '部⾨門名 -> "近畿⽀支店",
'親部⾨門名 -> None), '親部⾨門ID -> Some(12),
Map('部⾨門ID -> 11, '親部⾨門名 -> "⻄西⽇日本統括"),
'部⾨門名 -> "東⽇日本統括", Map('部⾨門ID -> 122,
'親部⾨門ID -> Some(1), '部⾨門名 -> "中国⽀支店",
'親部⾨門名 -> "営業統括"), '親部⾨門ID -> Some(12),
Map('部⾨門ID -> 12, '親部⾨門名 -> "⻄西⽇日本統括"),
'部⾨門名 -> "⻄西⽇日本統括", Map('部⾨門ID -> 123,
'親部⾨門ID -> Some(1), '部⾨門名 -> "四国⽀支店",
'親部⾨門名 -> "営業統括"), '親部⾨門ID -> Some(12),
Map('部⾨門ID -> 13, '親部⾨門名 -> "⻄西⽇日本統括"),
'部⾨門名 -> "⾸首都圏統括", Map('部⾨門ID -> 124,
'親部⾨門ID -> Some(1), '部⾨門名 -> "九州⽀支店",
'親部⾨門名 -> "営業統括"), '親部⾨門ID -> Some(12),
Map('部⾨門ID -> 111, '親部⾨門名 -> "⻄西⽇日本統括"),
'部⾨門名 -> "北北海道⽀支店", Map('部⾨門ID -> 125,
'親部⾨門ID -> Some(11), '部⾨門名 -> "沖縄⽀支店",
'親部⾨門名 -> "東⽇日本統括"), '親部⾨門ID -> Some(12),
Map('部⾨門ID -> 112, '親部⾨門名 -> "⻄西⽇日本統括"),
'部⾨門名 -> "東北北⽀支店", Map('部⾨門ID -> 131,
'親部⾨門ID -> Some(11), '部⾨門名 -> "東京⽀支店",
'親部⾨門名 -> "東⽇日本統括"), '親部⾨門ID -> Some(13),
Map('部⾨門ID -> 113, '親部⾨門名 -> "⾸首都圏統括"),
'部⾨門名 -> "北北陸陸⽀支店", Map('部⾨門ID -> 132,
'親部⾨門ID -> Some(11), '部⾨門名 -> "北北関東⽀支店",
'親部⾨門名 -> "東⽇日本統括"), '親部⾨門ID -> Some(13),
Map('部⾨門ID -> 114, '親部⾨門名 -> "⾸首都圏統括"),
'部⾨門名 -> "中部⽀支店", Map('部⾨門ID -> 133,
'親部⾨門ID -> Some(11), '部⾨門名 -> "南関東⽀支店",
'親部⾨門名 -> "東⽇日本統括"), '親部⾨門ID -> Some(13),
'親部⾨門名 -> "⾸首都圏統括"))
38. 部⾨門(1,営業統括,None,Some(None))
|
+- 部⾨門(11,東⽇日本統括,Some(1),Some(営業統括))
| |
| +- 部⾨門(111,北北海道⽀支店,Some(11),Some(東⽇日本統括))
| |
| +- 部⾨門(112,東北北⽀支店,Some(11),Some(東⽇日本統括))
| |
| +- 部⾨門(113,北北陸陸⽀支店,Some(11),Some(東⽇日本統括))
| |
| `- 部⾨門(114,中部⽀支店,Some(11),Some(東⽇日本統括))
|
+- 部⾨門(12,⻄西⽇日本統括,Some(1),Some(営業統括))
| |
| +- 部⾨門(121,近畿⽀支店,Some(12),Some(⻄西⽇日本統括))
| |
| +- 部⾨門(122,中国⽀支店,Some(12),Some(⻄西⽇日本統括))
| |
| +- 部⾨門(123,四国⽀支店,Some(12),Some(⻄西⽇日本統括))
| |
| +- 部⾨門(124,九州⽀支店,Some(12),Some(⻄西⽇日本統括))
| |
| `- 部⾨門(125,沖縄⽀支店,Some(12),Some(⻄西⽇日本統括))
|
`- 部⾨門(13,⾸首都圏統括,Some(1),Some(営業統括))
|
+- 部⾨門(131,東京⽀支店,Some(13),Some(⾸首都圏統括))
|
+- 部⾨門(132,北北関東⽀支店,Some(13),Some(⾸首都圏統括))
|
`- 部⾨門(133,南関東⽀支店,Some(13),Some(⾸首都圏統括))
39. 並列列プログラミング
準備
時間を測る関数 テスト関数
def go[T](a: => T): (T, Long) = {
val start = System.currentTimeMillis val f = (x: Int) => {
val r = a Thread.sleep(x * 100)
val end = System.currentTimeMillis x
(r, end - start) }
}
scala> go(f(10)) scala> go {
res176: (Int, Long) = (10,1000) | f(10)
|}
res253: (Int, Long) = (10,1001)
40. PromiseのKleisli
scala> val fp = f.promise
fp: scalaz.Kleisli[scalaz.concurrent.Promise,Int,Int] =
scalaz.Kleislis$$anon$1@9edaab8
Applicative
scala> go((fp(1) |@| fp(2) |@| fp(3))(_ + _ + _).get)
res215: (Int, Long) = (6,302)
scala> go(f(1) + f(2) + f(3))
res212: (Int, Long) = (6,603)
scala> go((1.some |@| 2.some |@| 3.some)(_ + _ + _).get)
res237: (Int, Long) = (6,1)
41. scala> go(List(1, 2, 3).map(fp).map(_.flatMap(fp)).sequence.get)
res220: (List[Int], Long) = (List(1, 2, 3),602)
scala> go(List(1, 2, 3).map(f).map(f))
res221: (List[Int], Long) = (List(1, 2, 3),1205)
テスト関数
val fx = (x: Int) => {
val t = math.abs(x - 4)
Thread.sleep(t * 100)
x
}
val fxp = fx.promise
42. scala> go(List(1, 2, 3).map(fp).map(_.flatMap(fxp)).sequence.get)
res222: (List[Int], Long) = (List(1, 2, 3),402)
scala> go(List(1, 2, 3).map(f).map(fx))
res223: (List[Int], Long) = (List(1, 2, 3),1205)
scala> go(List(1, 2, 3).map(fp >=> fxp).sequence.get)
res230: (List[Int], Long) = (List(1, 2, 3),402)
scala> go(List(1, 2, 3).map(f >>> fx))
res232: (List[Int], Long) = (List(1, 2, 3),1205)
43. まとめ
• 関数型プログラミングの部品
• 代数的データ型
• 永続データ構造
• モナド
• 型クラス
• オブジェクト指向プログラミングの新技術
• トレイト
• OFP
• オブジェクト指向で関数型を束ねる
• DSL
• Scalable Laguage = Scala
• Scala
• OFPをやるならScalaしか選択肢がないかも
44.