SlideShare una empresa de Scribd logo
1 de 59
Descargar para leer sin conexión
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

Más contenido relacionado

La actualidad más candente

SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021Hiroshi Tokumaru
 
PostgreSQLアンチパターン
PostgreSQLアンチパターンPostgreSQLアンチパターン
PostgreSQLアンチパターンSoudai Sone
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪Takuto Wada
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)NTT DATA Technology & Innovation
 
ブレソルでテラバイト級データのALTERを短時間で終わらせる
ブレソルでテラバイト級データのALTERを短時間で終わらせるブレソルでテラバイト級データのALTERを短時間で終わらせる
ブレソルでテラバイト級データのALTERを短時間で終わらせるKLab Inc. / Tech
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」Takuto Wada
 
REST API のコツ
REST API のコツREST API のコツ
REST API のコツpospome
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話Koichiro Matsuoka
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用nagise
 
人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with Karate人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with KarateTakanori Suzuki
 
マイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチマイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチ増田 亨
 
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考えるGoのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考えるpospome
 
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうPython 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうRyuji Tsutsui
 
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティスAmazon Web Services Japan
 
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3 データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3 Hiroshi Ito
 
グラフデータベース入門
グラフデータベース入門グラフデータベース入門
グラフデータベース入門Masaya Dake
 
PostgreSQLアーキテクチャ入門(INSIGHT OUT 2011)
PostgreSQLアーキテクチャ入門(INSIGHT OUT 2011)PostgreSQLアーキテクチャ入門(INSIGHT OUT 2011)
PostgreSQLアーキテクチャ入門(INSIGHT OUT 2011)Uptime Technologies LLC (JP)
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法についてYuji Otani
 

La actualidad más candente (20)

SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021
 
PostgreSQLアンチパターン
PostgreSQLアンチパターンPostgreSQLアンチパターン
PostgreSQLアンチパターン
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
 
ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開
 
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
今こそ知りたいSpring Batch(Spring Fest 2020講演資料)
 
ブレソルでテラバイト級データのALTERを短時間で終わらせる
ブレソルでテラバイト級データのALTERを短時間で終わらせるブレソルでテラバイト級データのALTERを短時間で終わらせる
ブレソルでテラバイト級データのALTERを短時間で終わらせる
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
 
REST API のコツ
REST API のコツREST API のコツ
REST API のコツ
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用
 
人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with Karate人生がときめくAPIテスト自動化 with Karate
人生がときめくAPIテスト自動化 with Karate
 
マイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチマイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチ
 
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考えるGoのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
 
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうPython 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそう
 
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
[Aurora事例祭り]Amazon Aurora を使いこなすためのベストプラクティス
 
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3 データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
 
グラフデータベース入門
グラフデータベース入門グラフデータベース入門
グラフデータベース入門
 
PostgreSQLアーキテクチャ入門(INSIGHT OUT 2011)
PostgreSQLアーキテクチャ入門(INSIGHT OUT 2011)PostgreSQLアーキテクチャ入門(INSIGHT OUT 2011)
PostgreSQLアーキテクチャ入門(INSIGHT OUT 2011)
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
 

Destacado

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 akkaTaisuke Oe
 
Non-Functional Programming in Scala
Non-Functional Programming in ScalaNon-Functional Programming in Scala
Non-Functional Programming in Scalatakezoe
 
DeNAの機械学習・深層学習活用した 体験提供の挑戦
DeNAの機械学習・深層学習活用した体験提供の挑戦DeNAの機械学習・深層学習活用した体験提供の挑戦
DeNAの機械学習・深層学習活用した 体験提供の挑戦Koichi Hamada
 
20170721 future of reactive architectures
20170721 future of reactive architectures20170721 future of reactive architectures
20170721 future of reactive architecturesJamie 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 BayAdam Gibson
 
バイナリニューラルネットとハードウェアの関係
バイナリニューラルネットとハードウェアの関係バイナリニューラルネットとハードウェアの関係
バイナリニューラルネットとハードウェアの関係Kento Tajiri
 
強くなるためのプログラミング -プログラミングに関する様々なコンテストとそのはじめ方-#pyconjp
強くなるためのプログラミング -プログラミングに関する様々なコンテストとそのはじめ方-#pyconjp強くなるためのプログラミング -プログラミングに関する様々なコンテストとそのはじめ方-#pyconjp
強くなるためのプログラミング -プログラミングに関する様々なコンテストとそのはじめ方-#pyconjpcocodrips
 
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 DNNnotogawa
 
TensorFlow XLAの可能性
TensorFlow XLAの可能性 TensorFlow XLAの可能性
TensorFlow XLAの可能性 Mr. Vengineer
 
モデルアーキテクチャ観点からのDeep Neural Network高速化
モデルアーキテクチャ観点からのDeep Neural Network高速化モデルアーキテクチャ観点からのDeep Neural Network高速化
モデルアーキテクチャ観点からのDeep Neural Network高速化Yusuke Uchida
 

Destacado (16)

iOSエンジニアのためのScala入門
iOSエンジニアのためのScala入門iOSエンジニアのためのScala入門
iOSエンジニアのためのScala入門
 
元インフラエンジニアが
Scalaを触ってつまづいたところ。
元インフラエンジニアが
Scalaを触ってつまづいたところ。元インフラエンジニアが
Scalaを触ってつまづいたところ。
元インフラエンジニアが
Scalaを触ってつまづいたところ。
 
BigDLでScala × DeepLearning に入門した話
BigDLでScala × DeepLearning に入門した話BigDLでScala × DeepLearning に入門した話
BigDLでScala × DeepLearning に入門した話
 
What Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミットWhat Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミット
 
Real world android akka
Real world android akkaReal world android akka
Real world android akka
 
Non-Functional Programming in Scala
Non-Functional Programming in ScalaNon-Functional Programming in Scala
Non-Functional Programming in Scala
 
DeNAの機械学習・深層学習活用した 体験提供の挑戦
DeNAの機械学習・深層学習活用した体験提供の挑戦DeNAの機械学習・深層学習活用した体験提供の挑戦
DeNAの機械学習・深層学習活用した 体験提供の挑戦
 
20170721 future of reactive architectures
20170721 future of reactive architectures20170721 future of reactive architectures
20170721 future of reactive architectures
 
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
 
バイナリニューラルネットとハードウェアの関係
バイナリニューラルネットとハードウェアの関係バイナリニューラルネットとハードウェアの関係
バイナリニューラルネットとハードウェアの関係
 
強くなるためのプログラミング -プログラミングに関する様々なコンテストとそのはじめ方-#pyconjp
強くなるためのプログラミング -プログラミングに関する様々なコンテストとそのはじめ方-#pyconjp強くなるためのプログラミング -プログラミングに関する様々なコンテストとそのはじめ方-#pyconjp
強くなるためのプログラミング -プログラミングに関する様々なコンテストとそのはじめ方-#pyconjp
 
CTFはとんでもないものを 盗んでいきました。私の時間です…
CTFはとんでもないものを 盗んでいきました。私の時間です…CTFはとんでもないものを 盗んでいきました。私の時間です…
CTFはとんでもないものを 盗んでいきました。私の時間です…
 
Go入門
Go入門Go入門
Go入門
 
Using Raspberry Pi GPU for DNN
Using Raspberry Pi GPU for DNNUsing Raspberry Pi GPU for DNN
Using Raspberry Pi GPU for DNN
 
TensorFlow XLAの可能性
TensorFlow XLAの可能性 TensorFlow XLAの可能性
TensorFlow XLAの可能性
 
モデルアーキテクチャ観点からのDeep Neural Network高速化
モデルアーキテクチャ観点からのDeep Neural Network高速化モデルアーキテクチャ観点からのDeep Neural Network高速化
モデルアーキテクチャ観点からのDeep Neural Network高速化
 

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

プログラミング言語Scala
プログラミング言語Scalaプログラミング言語Scala
プログラミング言語ScalaTanUkkii
 
ゼロから始める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
 
オブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional Programmingオブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional ProgrammingTomoharu 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.pdfHiroshi Ono
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdfHiroshi Ono
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdfHiroshi Ono
 
Nds meetup8 lt
Nds meetup8 ltNds meetup8 lt
Nds meetup8 ltushiboy
 
実務者のためのかんたんScalaz
実務者のためのかんたんScalaz実務者のためのかんたんScalaz
実務者のためのかんたんScalazTomoharu ASAMI
 
初心者講習会資料(Osaka.r#6)
初心者講習会資料(Osaka.r#6)初心者講習会資料(Osaka.r#6)
初心者講習会資料(Osaka.r#6)Masahiro Hayashi
 

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

たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
プログラミング言語Scala
プログラミング言語Scalaプログラミング言語Scala
プログラミング言語Scala
 
ゼロから始めるScala文法 (再)
ゼロから始めるScala文法 (再)ゼロから始めるScala文法 (再)
ゼロから始めるScala文法 (再)
 
Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]
 
Scalaプログラミング・マニアックス
Scalaプログラミング・マニアックスScalaプログラミング・マニアックス
Scalaプログラミング・マニアックス
 
オブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional Programmingオブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional Programming
 
Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]
 
scala.collection 再入門 (改)
scala.collection 再入門 (改)scala.collection 再入門 (改)
scala.collection 再入門 (改)
 
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
 
関数型言語&形式的手法セミナー(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 〜型が付くってスバラシイ〜
 
初心者講習会資料(Osaka.R#5)
初心者講習会資料(Osaka.R#5)初心者講習会資料(Osaka.R#5)
初心者講習会資料(Osaka.R#5)
 
Haskell超入門 Part.1
Haskell超入門 Part.1Haskell超入門 Part.1
Haskell超入門 Part.1
 
ATN No.2 Scala事始め
ATN No.2 Scala事始めATN No.2 Scala事始め
ATN No.2 Scala事始め
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 
Nds meetup8 lt
Nds meetup8 ltNds meetup8 lt
Nds meetup8 lt
 
実務者のためのかんたんScalaz
実務者のためのかんたんScalaz実務者のためのかんたんScalaz
実務者のためのかんたんScalaz
 
初心者講習会資料(Osaka.r#6)
初心者講習会資料(Osaka.r#6)初心者講習会資料(Osaka.r#6)
初心者講習会資料(Osaka.r#6)
 

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