SlideShare a Scribd company logo
Scala の関数型プログラミング
を支える技術
2017/09/09 Scala関西Summit 2017
1 / 59
Whoami
Naoki Aoyama
Twitter: @AoiroAoino
GitHub: @aoiroaoino
Monocle コミッター
(株)セプテーニ・オリジナル
2 / 59
3 / 59
前提
Scala 2.12.3 時点での話です。
また、発表中の「一般的」という表現は静的型付き言語を前提とします。
話さないこと
Scala の基本的な文法
教育
歴史や時代背景
Haskell
数学的素養が求められる話
4 / 59
Agenda
関数型プログラミングとは?
関数
参照透過と副作用
純粋関数を用いたプログラミング
多相性
多相性の種類
型クラスとは
実は身近な存在
なぜ、型クラスが重要なのか
あれもこれも型クラス
「map が使える」型クラス
「for 式が使える」型クラス
まとめ
5 / 59
関数型プログラミングとは?
6 / 59
関数型プログラミングとは?
「関数」を用いて行うコーディングスタイル。
値に関数を適用していく事で計算を進めていく。
7 / 59
関数
8 / 59
関数
Scala の関数
Scala の関数はファーストクラス。
変数に代入したり、他の関数の引数に渡したり出来る。
val inc = (i: Int) => i + 1
val cl: String => Int => String =
(msg: String) => (rep: Int) => msg * rep
Scala では、変数/定数定義で型パラメータをとるような値は定義出来ない。メソッ
ド定義で代用するので、便宜上def を用いた定義も関数と呼ぶこととする。
def show[A]: A => String = (a: A) => a.toString
9 / 59
関数
Scala の関数
関数を引数にとったり、返り値として返したりする関数を高階関数と呼ぶ。
val calc: (Int => Int => Int) => Int => Int => Int =
(f: Int => Int => Int) => (i: Int) => (j: Int) => f(i)(j)
val add: Int => Int => Int =
(i: Int) => (j: Int) => i + j
val multi: Int => Int => Int =
(i: Int) => (j: Int) => i * j
scala> calc(add)(1)(2)
res15: Int = 3
scala> calc(multi)(1)(2)
res16: Int = 2
10 / 59
関数
参照透過
ここで登場する「関数」は数学的な関数ほぼそのまま。
参照透過とは、関数適用の結果が明示的に与えた引数の値にのみ依存する性質の
事。例えば、関数が同じ引数で二回呼ばれたら同じ値を返す。このような性質を
参照透過性と言い、参照透過な関数を純粋関数と呼ぶ。
val add = (i: Int) => (j: Int) => i + j
scala> add(1)(2)
res0: Int = 3
scala> add(1)(2)
res1: Int = 3
11 / 59
関数
純粋関数のメリット
純粋関数を用いることで例えば以下のようなメリットを享受出来る。
メンテナンスしやすい
再利用性が高くなる
テストしやすい
バグが発生しにくい
最適化を行いやすい
並列実行させやすい
etc...
Scala では関数が純粋であることを強制しない。メリットを得る為に可能な限り純
粋関数であることが望ましい。
12 / 59
関数
純粋関数のメリット
純粋関数intToChar とcharToString を合成して、新たにintToString という関数
を得られる。純粋関数であるため型で表現される事以外の作用を及ぼさないので、
型を見るだけで実装を推測しやすく、メンテナンス性も得られる。
val intToChar: Int => Char =
(i: Int) => i.toChar
val charToString: Char => String =
(c: Char) => c.toString
val intToString = intToChar andThen charToString
// or
val intToString = charToString compose intToChar
scala> intToString(97)
res21: String = a
13 / 59
関数
副作用
参照透過でない、外部に及ぼす/外部の影響を受ける作用(処理)。グローバルな
値が破壊的変更されたり、環境やタイミングによって結果が変わってしまう。
var counter = 100
def incCounter(): Unit =
counter = counter + 1
def printCounter(): Unit =
println(counter)
14 / 59
関数
副作用
val now = () => System.currentTimeMillis()
scala> now()
res1: Long = 1504897705832
scala> now()
res2: Long = 1504897708058
val isExistsFile: String => Boolean =
(fileName: String) => new java.io.File(fileName).exists
scala> isExistsFile("/tmp/file.txt")
res24: Boolean = false
// $ touch /tmp/file.txt
scala> isExistsFile("/tmp/file.txt")
res25: Boolean = true
15 / 59
関数
イミュータブルなデータ構造
破壊的代入や状態の操作など、副作用のある操作を行えない。この純粋関数の考え
方をデータ型に対しても適用するとイミュータブルなデータ構造となる。操作の実
行後は新しい操作後のデータが返され、操作前のデータはそのまま残る。
scala> val l = List(1, 2, 3)
l: List[Int] = List(1, 2, 3)
scala> l.map(_ * 10)
res0: List[Int] = List(10, 20, 30)
scala> l
res1: List[Int] = List(1, 2, 3)
16 / 59
多相性
17 / 59
多相性
関数型言語特有の概念ではない。
しかし、関数型プログラミングを行う上でも重要な要素。
多相性にはいくつか種類がある。
サブタイプ多相
パラメトリック多相
アドホック多相
18 / 59
多相性
パラメトリック多相
複数の型が型パラメータを使って統一的に表現できる多相。
sealed abstract class List[+A] extends ... { ... }
val strList = List("foo", "bar", "baz")
val intList = List(1, 2, 3)
sealed abstract class Option[+A] extends ... { ... }
final case class Some[+A](value: A) extends Option[A] { ... }
case object None extends Option[Nothing] { ... }
val strOpt = Option("foo")
val intOpt = Option(100)
19 / 59
多相性
パラメトリック多相
Scala では高カインド型も扱うことが出来る。
型コンストラクタをとる型コンストラクタ。
trait Cache[F[_]] {
def get[A](key: String): F[A]
}
class TryCache[Try] {
def get[A](key: String): Try[A] = ???
}
class OptionCache[Option] {
def get[A](key: String): Option[A] = ???
}
20 / 59
多相性
アドホック多相
ある関数に複数の型の値が与えられるが、それらの型の間に特に関連性がないよう
な多相の事を指す。
主にオーバーロードによって実現される。特に演算子の場合は言語の組み込み機能
として提供され、プログラマーが拡張出来ないことがしばしば。
def combine(i: Int, j: Int): Int = i + j
def combine(i: String, j: String): String = i + j
21 / 59
型クラス
22 / 59
型クラス
アドホック多相を実現するためのアプローチ(デザインパターン)。
Scala のimplicit parameter は型クラスを実現する為の機能。
23 / 59
型クラス
implicit parameter
暗黙の値とも。implicit が付いた引数を暗黙のうちに供給される。
def hello(msg: String)(implicit suffix: String): String =
msg + suffix
scala> hello("John")
<console>:13: error: could not find implicit value for parameter suffix: String
hello("John")
^
scala> implicit val s: String = "!!!"
s: String = !!!
scala> hello("John")
res1: String = John!!!
24 / 59
型クラス
implicit parameter
よく使われる標準機能。
Context Bound 暗黙の値を定義する際の糖衣構文。
def foo[A: Ordering](a: A): Int = ???
下記のように展開される。
def foo[A](a: A)(implicit x: Ordering[A]): Int = ???
implicitly 暗黙の引数を召喚する為の便利メソッド。scala.Predefより。
@inline def implicitly[T](implicit e: T) = e
25 / 59
型クラス
Ordering(Scala の標準ライブラリより)
// List#sorted の場合、Repr は List[A]
def sorted[B >: A](implicit ord: Ordering[B]): Repr = {
...
}
// List#max の場合、A は List の要素の型
def max[B >: A](implicit cmp: Ordering[B]): A = {
...
}
trait Ordering[T] extends Comparator[T] with PartialOrdering[T] with Serializable {
...
def compare(x: T, y: T): Int
...
}
26 / 59
型クラス
Ordering(Scala の標準ライブラリより)
自分で定義したデータ
sealed abstract class Num(val i: Int)
case object Zero extends Num(0)
case object One extends Num(1)
case object Two extends Num(2)
implicit val numOrdering: Ordering[Num] = new Ordering[Num] {
def compare(x: Num, y: Num): Int =
if (x.i == y.i) 0
else if (x.i < y.i) -1
else 1
}
scala> List[Num](One, Two, Zero).max
res4: Num = Two
scala> List[Num](One, Two, Zero).sorted
res6: List[Num] = List(Zero, One, Two)
27 / 59
型クラス
TypeBinder(scalikejdbc 公式ドキュメントより)
import scalikejdbc._
import java.sql.ResultSet
case class MemberId(id: Long)
implicit val memberIdTypeBinder: TypeBinder[MemberId] = new TypeBinder[MemberId] {
def apply(rs: ResultSet, label: String): MemberId = MemberId(rs.getLong(label))
def apply(rs: ResultSet, index: Int): MemberId = MemberId(rs.getLong(index))
}
val ids: Seq[MemberId] = sql"select id from member".map(_.get[MemberId]("id")).list.apply()
case class WrappedResultSet(underlying: ResultSet, cursor: ResultSetCursor, index:
//...
def get[A: TypeBinder](columnLabel: String): A = {
ensureCursor()
wrapIfError(implicitly[TypeBinder[A]].apply(underlying, columnLabel))
}
}
28 / 59
型クラス
「文字列に変換する」型クラス
trait Show[A] {
def show(a: A): String
}
object Show {
implicit val stringShow: Show[String] = new Show[String] {
def show(a: String): String = a
}
implicit val intShow: Show[Int] = new Show[Int] {
def show(a: Int): String = a.toString
}
}
29 / 59
型クラス
「文字列に変換する」型クラス
def show[A](a: A)(implicit sa: Show[A]): String =
sa.show(a)
scala> show(100)
res2: String = 100
scala> show("foo")
res3: String = foo
scala> show('a')
<console>:14: error: could not find implicit value for parameter sa: Show[Char]
show('a')
^
30 / 59
型クラス
「文字列に変換する」型クラス
scala> case class Cat(name: String)
defined class Cat
scala> implicit val catShow: Show[Cat] = new Show[Cat] {
| def show(a: Cat): String = s"${a.name} say, meow!"
| }
catShow: Show[Cat] = $anon$1@71179b6f
scala> show(Cat("moko"))
res5: String = moko say, meow!
31 / 59
型クラス
「なんか結合できる」型クラス
trait Additive[A] {
def combine(x: A, y: A): A
}
object Additive {
implicit val stringAdditive: Additive[String] = new Additive[String] {
def combine(x: String, y: String): String =
x + y
}
}
32 / 59
型クラス
「なんか結合できる」型クラス
def combine[A](a: A, b: A)(implicit aa: Additive[A]): A =
aa.combine(a, b)
scala> combine("foo", "bar")
res10: String = foobar
case class Natural(i: Int)
implicit val naturalAdditive: Additive[Natural] = new Additive[Natural] {
def combine(x: Natural, y: Natural): Natural =
Natural(x.i + y.i)
}
scala> combine(Natural(1), Natural(2))
res0: Natural = Natural(3)
33 / 59
型クラス
Enrich my library
implicit conversion を組み合わせることで、あたかも既存のデータ型に対してメ
ソッドが定義されているかのように見せかけることが出来る。
implicit class ShowOp[A](a: A) {
def show(implicit sa: Show[A]): String =
sa.show(a)
}
scala> 100.show
res7: String = 100
scala> Cat("moko").show
res8: String = moko say, meow!
34 / 59
型クラス
Enrich my library
implicit class AdditiveOp[A](a: A) {
def combine(b: A)(implicit aa: Additive[A]): A =
aa.combine(a, b)
}
scala> Natural(1) combine Natural(2)
res1: Natural = Natural(3)
35 / 59
型クラス
なぜ、型クラスが重要なのか
以下のようなMyList について考えてみる。
sealed abstract class MyList[+A]
case class MyCons[A](val head: A, val tail: MyList[A]) extends MyList[A]
case object MyNil extends MyList[Nothing]
scala> val l: MyList[Int] = MyCons(1, MyCons(2, MyCons(3, MyNil)))
l: MyList[Int] = MyCons(1,MyCons(2,MyCons(3,MyNil)))
36 / 59
型クラス
なぜ、型クラスが重要なのか
主に、オブジェクト指向ではMyList などのデータ構造に対してメソッドを追加す
るようなアプローチをとることが多い。
sealed abstract class MyList[+A] {
// メソッドの追加
def map(f: A => B): MyList[B] = ???
}
37 / 59
型クラス
なぜ、型クラスが重要なのか
関数型プログラミングでは異なるアプローチをとる。既存のデータ型を型クラスを
用いて操作を追加する。
implicit val mappable: Mappable[MyList] = new Mappable[MyList] {
def map[A, B](fa: MyList[A])(f: A => B): MyList[B] = ???
}
38 / 59
型クラス
なぜ、型クラスが重要なのか
このような関数型プログラミングのアプローチによって
標準ライブラリや外部ライブラリで定義されたデータ構造の拡張できる
自作データ型の操作を型クラスのインスタンスを定義することで容易に、
そして既存のデータ型と共通の名前、シグネチャの操作を得ることができる
データ構造とその操作を分離できる
などのメリットを享受できる。
39 / 59
あれもこれも型クラス
40 / 59
あれもこれも型クラス
より抽象的な型クラスを考えてみよう。
41 / 59
あれもこれも型クラス
「map が使える」型クラス
Option#map
scala> Option("Hello").map(s => s + "!!!")
res0: Option[String] = Some(Hello!!!)
List#map
scala> List(1, 2, 3).map(i => i * 10)
res2: List[Int] = List(10, 20, 30)
42 / 59
あれもこれも型クラス
「map が使える」型クラス
trait Mappable[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
object Mappable {
implicit val optionMappable: Mappable[Option] = new Mappable[Option] {
def map[A, B](a: Option[A])(f: A => B): Option[B] =
a.map(f)
}
implicit val listMappable: Mappable[List] = new Mappable[List] {
def map[A, B](a: List[A])(f: A => B): List[B] =
a.map(f)
}
}
43 / 59
あれもこれも型クラス
「map が使える」型クラス
使い方
scala> implicitly[Mappable[Option]].map(Option(100))(i => i + 1)
res3: Option[Int] = Some(101)
scala> implicitly[Mappable[List]].map(List(1, 2, 3))(i => i + 1)
res4: List[Int] = List(2, 3, 4)
44 / 59
あれもこれも型クラス
for 式再説
Scala のfor 式は糖衣構文。
val fooOpt: Option[Int] = ...
val barOpt: Option[Int] = ...
for {
foo <- fooOpt
bar <- barOpt
} yield foo + bar
以下のように展開される。
fooOpt.flatMap(foo =>
barOpt.map(bar =>
foo + bar
)
)
45 / 59
あれもこれも型クラス
for 式再説
for 式の展開には他にもルールがある。compiler の型付け前に展開されるので、
必ず全ての展開対象メソッドを実装している必要はない。
abstract class C[A] {
def map[B](f: A => B): C[B]
def flatMap[B](f: A => C[B]): C[B]
def withFilter([: A => Boolean): C[A]
def foreach(b: A => Unit): Unit
}
46 / 59
あれもこれも型クラス
「for 式が使える」型クラス
便宜上map, flatMap のみを考える。
trait CanWriteForSyntax[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
}
例えば、Option のインスタンスは以下の通り。
implicit val optionCanWriteForSyntax: CanWriteForSyntax[Option] =
new CanWriteForSyntax[Option] {
def map[A, B](fa: Option[A])(f: A => B): Option[B] =
fa.map(f)
def flatMap[A, B](fa: Option[A])(f: A => Option[B]): Option[B] =
fa.flatMap(f)
}
47 / 59
あれもこれも型クラス
「for 式が使える」型クラス
標準機能で求められるmap, flatMap とはシグネチャが異なるので、実際に使う場
合にはimplicit conversion と組み合わせる必要がある。
implicit class CanWriteForSyntaxOp[F[_], A](fa: F[A])(implicit x: CanWriteForSyntax
def map[B](f: A => B): F[B] =
x.map(fa)(f)
def flatMap[B](f: A => F[B]): F[B] =
x.flatMap(fa)(f)
}
48 / 59
あれもこれも型クラス
「for 式が使える」型クラス
def foo[F[_]: CanWriteForSyntax, A, B](fa: F[A]): F[String] =
for {
a <- fa
} yield a.toString
scala> foo(Option(100))
res6: Option[String] = Some(100)
49 / 59
あれもこれも型クラス
「for 式が使える」型クラス
もちろん、自作のデータ型に対しても定義出来る。
case class Response[A](value: A)
implicit val responseCanWriteForSyntax: CanWriteForSyntax[Response] =
new CanWriteForSyntax[Response] {
def map[A, B](fa: Response[A])(f: A => B): Response[B] =
fa.copy(value = f(fa.value))
def flatMap[A, B](fa: Response[A])(f: A => Response[B]): Response[B] =
fa match {
case Response(v) => f(v)
}
}
scala> foo(Response(100))
res13: Response[String] = Response(100)
50 / 59
あれもこれも型クラス
「for 式が使える」型クラス
Cache に対する操作を考えてみる。
abstract class SyncCache {
def get[A](key: String): Try[A]
def set[A](key: String, value: A): Try[Unit]
def update[A](key: String, f: A => A): Try[Unit]
}
abstract class AsyncCache {
def get[A](key: String): Future[A]
def set[A](key: String, value: A): Future[Unit]
def update[A](key: String, f: A => A): Future[Unit]
}
51 / 59
あれもこれも型クラス
update という処理はget とset という二つの関数をmap, flatMap による合成で実
装できる。
class SyncCache {
def get[A](key: String): Try[A]
def set[A](key: String, value: A): Try[Unit]
def update[A](key: String, f: A => A): Try[Unit] =
for {
v <- get[A](key)
_ <- set(key, f(v))
} yield ()
}
class AsyncCache {
def get[A](key: String): Future[A]
def set[A](key: String, value: A): Future[Unit]
def update[A](key: String, f: A => A): Future[Unit] =
for {
v <- get[A](key)
_ <- set(key, f(v))
} yield ()
}
52 / 59
あれもこれも型クラス
返り値の型をF[_] という型パラメータをとる型パラメータに包むことで共通化でき
る。ただし、update ではF[_] がmap, flatMap が定義されていることを知らない
(保証出来ない)。
abstract class Cache[F[_]] {
def get[A](key: String): F[A]
def set[A](key: String, value: A): F[Unit]
// compile 出来なくなる
def update[A](key: String, f: A => A): F[Unit] =
for {
v <- get[A](key)
_ <- set(key, f(v))
} yield ()
}
class SyncCache extends Cache[Try] { ... }
class AsyncCache extends Cache[Future] { ... }
53 / 59
あれもこれも型クラス
F[_] にCanWriteForSyntax 型クラスのインスタンスであるという制約をかけれ
ば、map, flatMap の実装を持つことが保証されるのでcompile 出来る。※実際
にはCanWriteForSyntaxOp の定義も必要。
abstract class Cache[F[_]: CanWriteForSyntax] { ... }
implicit val tryCanWriteForSyntax: CanWriteForSyntax[Try] =
new CanWriteForSyntax[Try] {
def map[A, B](fa: Try[A])(f: A => B): Try[B] =
fa.map(f)
def flatMap[A, B](fa: Try[A])(f: A => Try[B]): Try[B] =
fa.flatMap(f)
}
implicit def futureCanWriteForSyntax(implicit ec: ExecutionContext): CanWriteForSyntax
new CanWriteForSyntax[Future] {
def map[A, B](fa: Future[A])(f: A => B): Future[B] =
fa.map(f)
def flatMap[A, B](fa: Future[A](f: A => Future[B]): Future[B] =
fa.flatMap(f)
}
54 / 59
あれもこれも型クラス
ただし
実用的にはTry やFuture のままでも十分であることが多い。
型クラスを介した実装の解決が行われる為、オーバーヘッドがある。
55 / 59
まとめ
56 / 59
紹介したもの
Scala の言語機能
Function
implicit parameter
implicitly
Context Bound
implicit conversion
型パラメータ
高カインド型
for 式
etc...
57 / 59
紹介したもの
デザインパターン(のようなもの)
型クラス
Enrich my library
58 / 59
最後に
関数プログラミングとは何か?
純粋関数を定義するモチベーションとメリット
改めて意識するとより抽象的に書けてボイラープレートが減らせる
Scala でFP を意識する際に覚えておきたい機能の紹介
関数型プログラミング楽しい
59 / 59
Ad

More Related Content

What's hot (20)

Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
yoku0825
 
Elasticsearch as a Distributed System
Elasticsearch as a Distributed SystemElasticsearch as a Distributed System
Elasticsearch as a Distributed System
Satoyuki Tsukano
 
HashMapとは?
HashMapとは?HashMapとは?
HashMapとは?
Trash Briefing ,Ltd
 
backlogsでもCI/CDする夢を見る
backlogsでもCI/CDする夢を見るbacklogsでもCI/CDする夢を見る
backlogsでもCI/CDする夢を見る
Takeru Maehara
 
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjug実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
Yahoo!デベロッパーネットワーク
 
なかったらINSERTしたいし、あるならロック取りたいやん?
なかったらINSERTしたいし、あるならロック取りたいやん?なかったらINSERTしたいし、あるならロック取りたいやん?
なかったらINSERTしたいし、あるならロック取りたいやん?
ichirin2501
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
Moriharu Ohzu
 
雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング
yoku0825
 
Node.js Native ESM への道 〜最終章: Babel / TypeScript Modules との闘い〜
Node.js Native ESM への道  〜最終章: Babel / TypeScript Modules との闘い〜Node.js Native ESM への道  〜最終章: Babel / TypeScript Modules との闘い〜
Node.js Native ESM への道 〜最終章: Babel / TypeScript Modules との闘い〜
Teppei Sato
 
ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門
増田 亨
 
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミングJavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
Kent Ohashi
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
Koichiro Matsuoka
 
ラムダ計算入門
ラムダ計算入門ラムダ計算入門
ラムダ計算入門
Eita Sugimoto
 
Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方
Taku Miyakawa
 
Serverless時代のJavaについて
Serverless時代のJavaについてServerless時代のJavaについて
Serverless時代のJavaについて
Amazon Web Services Japan
 
PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選
Tomoya Kawanishi
 
Domain Modeling Made Functional (DevTernity 2022)
Domain Modeling Made Functional (DevTernity 2022)Domain Modeling Made Functional (DevTernity 2022)
Domain Modeling Made Functional (DevTernity 2022)
Scott Wlaschin
 
Kafkaを使った マイクロサービス基盤 part2 +運用して起きたトラブル集
Kafkaを使った マイクロサービス基盤 part2 +運用して起きたトラブル集Kafkaを使った マイクロサービス基盤 part2 +運用して起きたトラブル集
Kafkaを使った マイクロサービス基盤 part2 +運用して起きたトラブル集
matsu_chara
 
ドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解するドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解する
増田 亨
 
強いて言えば「集約どう実装するのかな、を考える」な話
強いて言えば「集約どう実装するのかな、を考える」な話強いて言えば「集約どう実装するのかな、を考える」な話
強いて言えば「集約どう実装するのかな、を考える」な話
Yoshitaka Kawashima
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
yoku0825
 
Elasticsearch as a Distributed System
Elasticsearch as a Distributed SystemElasticsearch as a Distributed System
Elasticsearch as a Distributed System
Satoyuki Tsukano
 
backlogsでもCI/CDする夢を見る
backlogsでもCI/CDする夢を見るbacklogsでもCI/CDする夢を見る
backlogsでもCI/CDする夢を見る
Takeru Maehara
 
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjug実運用して分かったRabbit MQの良いところ・気をつけること #jjug
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
Yahoo!デベロッパーネットワーク
 
なかったらINSERTしたいし、あるならロック取りたいやん?
なかったらINSERTしたいし、あるならロック取りたいやん?なかったらINSERTしたいし、あるならロック取りたいやん?
なかったらINSERTしたいし、あるならロック取りたいやん?
ichirin2501
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
Moriharu Ohzu
 
雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング雑なMySQLパフォーマンスチューニング
雑なMySQLパフォーマンスチューニング
yoku0825
 
Node.js Native ESM への道 〜最終章: Babel / TypeScript Modules との闘い〜
Node.js Native ESM への道  〜最終章: Babel / TypeScript Modules との闘い〜Node.js Native ESM への道  〜最終章: Babel / TypeScript Modules との闘い〜
Node.js Native ESM への道 〜最終章: Babel / TypeScript Modules との闘い〜
Teppei Sato
 
ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門
増田 亨
 
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミングJavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
Kent Ohashi
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
Koichiro Matsuoka
 
ラムダ計算入門
ラムダ計算入門ラムダ計算入門
ラムダ計算入門
Eita Sugimoto
 
Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方
Taku Miyakawa
 
PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選
Tomoya Kawanishi
 
Domain Modeling Made Functional (DevTernity 2022)
Domain Modeling Made Functional (DevTernity 2022)Domain Modeling Made Functional (DevTernity 2022)
Domain Modeling Made Functional (DevTernity 2022)
Scott Wlaschin
 
Kafkaを使った マイクロサービス基盤 part2 +運用して起きたトラブル集
Kafkaを使った マイクロサービス基盤 part2 +運用して起きたトラブル集Kafkaを使った マイクロサービス基盤 part2 +運用して起きたトラブル集
Kafkaを使った マイクロサービス基盤 part2 +運用して起きたトラブル集
matsu_chara
 
ドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解するドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解する
増田 亨
 
強いて言えば「集約どう実装するのかな、を考える」な話
強いて言えば「集約どう実装するのかな、を考える」な話強いて言えば「集約どう実装するのかな、を考える」な話
強いて言えば「集約どう実装するのかな、を考える」な話
Yoshitaka Kawashima
 

Viewers also liked (16)

iOSエンジニアのためのScala入門
iOSエンジニアのためのScala入門iOSエンジニアのためのScala入門
iOSエンジニアのためのScala入門
Masaya Dake
 
元インフラエンジニアが
Scalaを触ってつまづいたところ。
元インフラエンジニアが
Scalaを触ってつまづいたところ。元インフラエンジニアが
Scalaを触ってつまづいたところ。
元インフラエンジニアが
Scalaを触ってつまづいたところ。
takako onoue
 
BigDLでScala × DeepLearning に入門した話
BigDLでScala × DeepLearning に入門した話BigDLでScala × DeepLearning に入門した話
BigDLでScala × DeepLearning に入門した話
hirotakanosato
 
What Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミットWhat Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミット
Taisuke Oe
 
Real world android akka
Real world android akkaReal world android akka
Real world android akka
Taisuke Oe
 
Non-Functional Programming in Scala
Non-Functional Programming in ScalaNon-Functional Programming in Scala
Non-Functional Programming in Scala
takezoe
 
DeNAの機械学習・深層学習活用した 体験提供の挑戦
DeNAの機械学習・深層学習活用した体験提供の挑戦DeNAの機械学習・深層学習活用した体験提供の挑戦
DeNAの機械学習・深層学習活用した 体験提供の挑戦
Koichi Hamada
 
20170721 future of reactive architectures
20170721 future of reactive architectures20170721 future of reactive architectures
20170721 future of reactive architectures
Jamie Allen
 
Deep Learning with GPUs in Production - AI By the Bay
Deep Learning with GPUs in Production - AI By the BayDeep Learning with GPUs in Production - AI By the Bay
Deep Learning with GPUs in Production - AI By the Bay
Adam Gibson
 
バイナリニューラルネットとハードウェアの関係
バイナリニューラルネットとハードウェアの関係バイナリニューラルネットとハードウェアの関係
バイナリニューラルネットとハードウェアの関係
Kento Tajiri
 
強くなるためのプログラミング -プログラミングに関する様々なコンテストとそのはじめ方-#pyconjp
強くなるためのプログラミング -プログラミングに関する様々なコンテストとそのはじめ方-#pyconjp強くなるためのプログラミング -プログラミングに関する様々なコンテストとそのはじめ方-#pyconjp
強くなるためのプログラミング -プログラミングに関する様々なコンテストとそのはじめ方-#pyconjp
cocodrips
 
CTFはとんでもないものを 盗んでいきました。私の時間です…
CTFはとんでもないものを 盗んでいきました。私の時間です…CTFはとんでもないものを 盗んでいきました。私の時間です…
CTFはとんでもないものを 盗んでいきました。私の時間です…
Hiromu Yakura
 
Go入門
Go入門Go入門
Go入門
Takuya Ueda
 
Using Raspberry Pi GPU for DNN
Using Raspberry Pi GPU for DNNUsing Raspberry Pi GPU for DNN
Using Raspberry Pi GPU for DNN
notogawa
 
TensorFlow XLAの可能性
TensorFlow XLAの可能性 TensorFlow XLAの可能性
TensorFlow XLAの可能性
Mr. Vengineer
 
モデルアーキテクチャ観点からのDeep Neural Network高速化
モデルアーキテクチャ観点からのDeep Neural Network高速化モデルアーキテクチャ観点からのDeep Neural Network高速化
モデルアーキテクチャ観点からのDeep Neural Network高速化
Yusuke Uchida
 
iOSエンジニアのためのScala入門
iOSエンジニアのためのScala入門iOSエンジニアのためのScala入門
iOSエンジニアのためのScala入門
Masaya Dake
 
元インフラエンジニアが
Scalaを触ってつまづいたところ。
元インフラエンジニアが
Scalaを触ってつまづいたところ。元インフラエンジニアが
Scalaを触ってつまづいたところ。
元インフラエンジニアが
Scalaを触ってつまづいたところ。
takako onoue
 
BigDLでScala × DeepLearning に入門した話
BigDLでScala × DeepLearning に入門した話BigDLでScala × DeepLearning に入門した話
BigDLでScala × DeepLearning に入門した話
hirotakanosato
 
What Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミットWhat Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミット
Taisuke Oe
 
Real world android akka
Real world android akkaReal world android akka
Real world android akka
Taisuke Oe
 
Non-Functional Programming in Scala
Non-Functional Programming in ScalaNon-Functional Programming in Scala
Non-Functional Programming in Scala
takezoe
 
DeNAの機械学習・深層学習活用した 体験提供の挑戦
DeNAの機械学習・深層学習活用した体験提供の挑戦DeNAの機械学習・深層学習活用した体験提供の挑戦
DeNAの機械学習・深層学習活用した 体験提供の挑戦
Koichi Hamada
 
20170721 future of reactive architectures
20170721 future of reactive architectures20170721 future of reactive architectures
20170721 future of reactive architectures
Jamie Allen
 
Deep Learning with GPUs in Production - AI By the Bay
Deep Learning with GPUs in Production - AI By the BayDeep Learning with GPUs in Production - AI By the Bay
Deep Learning with GPUs in Production - AI By the Bay
Adam Gibson
 
バイナリニューラルネットとハードウェアの関係
バイナリニューラルネットとハードウェアの関係バイナリニューラルネットとハードウェアの関係
バイナリニューラルネットとハードウェアの関係
Kento Tajiri
 
強くなるためのプログラミング -プログラミングに関する様々なコンテストとそのはじめ方-#pyconjp
強くなるためのプログラミング -プログラミングに関する様々なコンテストとそのはじめ方-#pyconjp強くなるためのプログラミング -プログラミングに関する様々なコンテストとそのはじめ方-#pyconjp
強くなるためのプログラミング -プログラミングに関する様々なコンテストとそのはじめ方-#pyconjp
cocodrips
 
CTFはとんでもないものを 盗んでいきました。私の時間です…
CTFはとんでもないものを 盗んでいきました。私の時間です…CTFはとんでもないものを 盗んでいきました。私の時間です…
CTFはとんでもないものを 盗んでいきました。私の時間です…
Hiromu Yakura
 
Using Raspberry Pi GPU for DNN
Using Raspberry Pi GPU for DNNUsing Raspberry Pi GPU for DNN
Using Raspberry Pi GPU for DNN
notogawa
 
TensorFlow XLAの可能性
TensorFlow XLAの可能性 TensorFlow XLAの可能性
TensorFlow XLAの可能性
Mr. Vengineer
 
モデルアーキテクチャ観点からのDeep Neural Network高速化
モデルアーキテクチャ観点からのDeep Neural Network高速化モデルアーキテクチャ観点からのDeep Neural Network高速化
モデルアーキテクチャ観点からのDeep Neural Network高速化
Yusuke Uchida
 
Ad

Similar to Scala の関数型プログラミングを支える技術 (20)

たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
Shinichi Kozake
 
プログラミング言語Scala
プログラミング言語Scalaプログラミング言語Scala
プログラミング言語Scala
TanUkkii
 
ゼロから始めるScala文法 (再)
ゼロから始めるScala文法 (再)ゼロから始めるScala文法 (再)
ゼロから始めるScala文法 (再)
Suguru Hamazaki
 
Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]
Ra Zon
 
Scalaプログラミング・マニアックス
Scalaプログラミング・マニアックスScalaプログラミング・マニアックス
Scalaプログラミング・マニアックス
Tomoharu ASAMI
 
純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala
純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala
純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala
Kent Ohashi
 
オブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional Programmingオブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional Programming
Tomoharu ASAMI
 
Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]
Ra Zon
 
scala.collection 再入門 (改)
scala.collection 再入門 (改)scala.collection 再入門 (改)
scala.collection 再入門 (改)
Ryuichi ITO
 
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
Ouka Yuka
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
啓 小笠原
 
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
 
初心者講習会資料(Osaka.R#5)
初心者講習会資料(Osaka.R#5)初心者講習会資料(Osaka.R#5)
初心者講習会資料(Osaka.R#5)
Masahiro Hayashi
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
Hiroshi Ono
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
Hiroshi Ono
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
Hiroshi Ono
 
Exploring Collections in JVM Languages through Internals of map Function
Exploring Collections in JVM Languages through Internals of map FunctionExploring Collections in JVM Languages through Internals of map Function
Exploring Collections in JVM Languages through Internals of map Function
Kent Ohashi
 
Nds meetup8 lt
Nds meetup8 ltNds meetup8 lt
Nds meetup8 lt
ushiboy
 
プログラミング言語Scala
プログラミング言語Scalaプログラミング言語Scala
プログラミング言語Scala
TanUkkii
 
ゼロから始めるScala文法 (再)
ゼロから始めるScala文法 (再)ゼロから始めるScala文法 (再)
ゼロから始めるScala文法 (再)
Suguru Hamazaki
 
Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]
Ra Zon
 
Scalaプログラミング・マニアックス
Scalaプログラミング・マニアックスScalaプログラミング・マニアックス
Scalaプログラミング・マニアックス
Tomoharu ASAMI
 
純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala
純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala
純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala
Kent Ohashi
 
オブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional Programmingオブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional Programming
Tomoharu ASAMI
 
Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]
Ra Zon
 
scala.collection 再入門 (改)
scala.collection 再入門 (改)scala.collection 再入門 (改)
scala.collection 再入門 (改)
Ryuichi ITO
 
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
Ouka Yuka
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
啓 小笠原
 
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
 
初心者講習会資料(Osaka.R#5)
初心者講習会資料(Osaka.R#5)初心者講習会資料(Osaka.R#5)
初心者講習会資料(Osaka.R#5)
Masahiro Hayashi
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
Hiroshi Ono
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
Hiroshi Ono
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
Hiroshi Ono
 
Exploring Collections in JVM Languages through Internals of map Function
Exploring Collections in JVM Languages through Internals of map FunctionExploring Collections in JVM Languages through Internals of map Function
Exploring Collections in JVM Languages through Internals of map Function
Kent Ohashi
 
Nds meetup8 lt
Nds meetup8 ltNds meetup8 lt
Nds meetup8 lt
ushiboy
 
Ad

Scala の関数型プログラミングを支える技術