SlideShare una empresa de Scribd logo
1 de 93
Descargar para leer sin conexión
Real World Cats
@ikhoon
1
!
- , (~ 2015)
!
- ? (2016)
Category theory
!
- ... ! (2017)
Pure functional
!
- (2018 ~)
...
2
, y = f(x)
1. ?
3
, y = f(x)
1. ?
: 3, 4
"
." 29
29
https://ko.wikipedia.org/wiki/
%ED%95%A8%EC%88%98#%EB%B6%80%EB%B6%84_%EC%A0%95%EC%9D%
98_%ED%95%A8%EC%88%98_%C2%B7_%EB%8B%A4%EA%B0%80_%ED%95
%A8%EC%88%98
4
, y = f(x)
?
2. ?
5
...
6
def factorial(n: Int): Either[String, BigInt] =
if (n < 0) Left("n 0 ")
else if (n == 0) Right(1)
else factorial(n - 1).map(_ * n)
cats .
Either Monadic cats ;-)
7
+
8
2
— They’re easier to reason about
— They’re easier to combine
— They’re easier to test
— They’re easier to debug
— They’re easier to parallelize
— They are idempotent
— They offer referential transparency
— They are memoizable
— They can be lazy
2
Book, Functional Programming Simplified - Alvin
Alexander
9
— .
(compose), (parallel)
(memoize), (lazy) .
— DRY(Don't Repeat Yourself)
10
?
1 - ?
—
— Scala with Cats15
— , "scala cats" 458,000
15
https://underscore.io/training/courses/advanced-scala/
11
?
2 - ?
— 209
— 3452
— Pull Request 1524 (42 Open, 1482 Closed)
— 1.0.0 .
12
?
3 - ecosystem ?
— circe: pure functional JSON library
— doobie: a pure functional JDBC layer for Scala
— finch: Scala combinator library for building Finagle HTTP services
— FS2: compositional, streaming I/O library
— h!p4s: A minimal, idiomatic Scala interface for HTTP
— Monix: high-performance library for composing asynchronous and event-
based programs
31 .
13
Cats - .
14
Cats
— Typeclass .17
— Datatype ' A' typeclass instance ' A' typeclass .
— ex) Option(datatype) Monad(typeclass) (instance) (pure, flatMap)
.
17
http://learnyouahaskell.com/types-and-typeclasses
15
Cats
— Type classes 30
— Data types
— Instance
30
https://github.com/tpolecat/cats-infographic
16
Cats
— Type classes
— Data types
— Instance
.
!
Core .
.
17
Cats
— Type classes
— Data types
— Instance
18
Cats
— Type classes
— Data types
— Instance
cats .
OptionT EitherT
!!
.
19
Cats
— Type classes
— Data types
— Instance
Instance Datatype typeclass .
Data type type class .
.
core datatype core typeclass instance .18
18
https://typelevel.org/cats/typeclasses.html#incomplete-type-class-instances-in-cats
20
Cats - Monad ?
Monad .
Monad ?
21
Monad 8
C .
C -> C ,
End(C) . End(C)
, End(C)
. End(C)
C .
8
https://ko.wikipedia.org/wiki/
%EB%AA%A8%EB%82%98%EB%93%9C_(%EB%B2%94%
EC%A3%BC%EB%A1%A0)
22
Cats - Monad ?
Monad .
?
flatMap(Monad) .
23
Cats -
Ordered compare
4 (<, <=, >, >=) .
case class Version(major: Int, minor: Int, patch: Int) extends Ordered[Version] {
def compare(that: Version): Int =
if(major > that.major) 1
else if (major == that.major && minor > that.minor) 1 ...
else -1
}
Version(1, 11, 1) < Version(1, 1, 1) // false
Version(1, 10, 1) > Version(0, 0, 1) // true
Version(10, 9, 3) <= Version(0, 0, 1) // false
24
Monad
.
pure flatMap
!
.( 110 )
— map = pure + flatMap
— ap = flatMap + map
— product = map + ap
— map2 = map + product
25
Monad
.
def map[A, B](fa: F[A])(f: A => B): F[B] =
flatMap(fa)(f andThen pure)
def ap[A, B](fa: F[A])(ff: F[A => B]): F[B] =
flatMap(fa)(a => map(ff)(f => f(a)))
def product[A, B](fa: F[A], fb: F[B]): F[(A, B)] =
ap(fb)(map(fa)(a => (b: B) => (a, b)))
def map2[A, B, Z](fa: F[A], fb: F[B])(f: (A, B) => Z): F[Z] =
map(product(fa, fb))(f.tupled)
26
cats ...
...
!
" backup slide "
Cats
27
!
?
1.
2.
3. cache
4. nullable
28
1.
!
100 .
REST API API
100 API ...
GET /v1/api/items/:id
API 100 .
val itemIds: List[Int]
// API
def findItemById(itemId: Int): Future[Option[Item]]
29
API
Problem
API 100ms ?
100
10 ?! .
!
API
...
2 .
!
!
30
Solution
25
100 .
100
DDOS .
.
100 10 10
.
1 .
!
25
Reactive Microservices Architecture By Jonas Bonér,
Co-Founder & CTO Lightbend, Inc.
31
flatMap
.
traverse
(map) (reduce) .
flatMap traverse .
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
def traverse[G[_]: Applicative, A, B](fa: F[A])(f: A => G[B]): G[F[B]]
32
Future, Lazy, Parallel traverse
— Traverse
Traverse typeclass .
travese .
— Parallel (parTraverse, parMapN)
cats typeclass .
Scala Future Parallel instance .28
— Scala Future (Eager)
Eager evalution traverse .
— Monix Task (Lazy)
Lazy evaluation traverse .
monix Task parTraverse .
Monix Task .
def findItemById(itemId: Int): Task[Item] // Monix Task
itemIds.traverse(findItemById) // 10
itemIds.parTraverse(findItemById) // 1
28
https://www.reddit.com/r/scala/comments/7qimqg/cats_parallel_future_traverse/
33
10 , 10
API
- grouped : 10
- foldLeft : List
- flatMap : 10 10
- traverse : 10 .( parTraverse)
!
val items = itemIds
.grouped(10).toList //
.foldLeft(List.empty[Item].pure[Future]) ((acc, group) =>
acc.flatMap(xs => //
group.traverse(findItemById).map(xs ::: _))) //
34
1.
2.
35
2.
Problem
ID ID .
.
val itemIds: List[Int]
// API
def isActiveItem[F[_]](itemId: Int)(implicit F: Effect[F]): F[Boolean]
filter + async
36
2.
( ) .
// 1. map .
val step1: List[IO[(Int, Boolean)]] = itemIds.map(itemId =>
isActiveItem[IO](itemId).tupleLeft(itemId))
// 2. IO List
val step2: IO[List[(Int, Boolean)]] = step1.sequence
// 3. filter .
val step3: IO[List[(Int, Boolean)]] = step2.map(xs => xs.filter(_._2))
// 4. Boolean
val step4: IO[List[Int]] = step3.map(_.map(_._1))
37
.
!
.
?
38
.
!
.
?
!
!!!
filterA .
39
filterA
. . filterA .
import cats.mtl.implicits._
// filterA .
val activeItem: IO[List[Int]] = itemIds.filterA(isActiveItem[IO])
4 step filterA .
.
!
FP !!!
.
40
filterA
def filterA[G[_], A]
(fa: F[A])(f: A => G[Boolean])
(implicit G: Applicative[G]): G[F[A]]
— filterA predicate
A => G[Boolean] .
— G Applicative
Applicative instance List, Future, Option .
— filterA
.
f: A => Option[Boolean] .
41
cats 1.x filterA
cats 0.x filterA import
import cats.implicits._ // 0.x
cats 1.x filterA cats-mtl23
.
import .
libraryDependencies += "org.typelevel" %% "cats-mtl" % "0.2.1"
import cats.mtl.implicits._ // import
23
https://github.com/typelevel/cats-mtl/blob/f3bd9aa4c8c0466d8cb4aa25bfcc6480531929c5/
core/src/main/scala/cats/mtl/TraverseEmpty.scala#L48
42
1.
2.
3. cache
43
3. cache
!
cache .
Cache miss backup .
Problem - .
.
. .
cache layer .
def fetch[F[_]](id: Int)(implicit F: Effect[F]): F[Option[User]] =
fetchLocalCache(id).flatMap { //local cache
case cached @ Some(_) => F.pure(cached) //
case None => //
fetchRemoteCache(id).flatMap { //remote cache
case cached @ Some(_) => F.pure(cached)// .
case None => fetchDB(id) // DB .
}
}
44
Problem - .
def fetch[F[_]](id: Int)(implicit F: Effect[F]): F[Option[User]] =
fetchLocalCache(id).flatMap { // local cache
case cached @ Some(_) => F.pure(cached) //
case None => //
fetchRemoteCache(id).flatMap { // remote cache
case cached @ Some(_) => F.pure(cached) // .
case None => fetchDB(id) // DB .
}
}
45
Cache miss
cache layer
(pattern) ?
46
Cache miss
cache layer
(pattern) ?
!
!!!
SemigroupK
“pick the first winner” 10
.
10
Book, Functional Programming for Mortals with Scalaz - Sam Halliday
47
SemigroupK
- . F[A]
@typeclass trait SemigroupK[F[_]] {
@op("<+>") def combineK[A](x: F[A], y: F[A]): F[A]
}
- Plus (or as cats have renamed it, SemigroupK) has
"pick the first winner, ignore errors" semantics. Although
it is not expressed in its laws.11
11
https://github.com/typelevel/cats-effect/issues/94#issuecomment-351736393
48
SemigroupK - IO
IO .
.
// "First" . IO.apply lazy .
val res1 = IO { "First" } <+> IO { "Second" }
res1.unsafeRunSync() // res1: "First"
// "First Error"
!
"Second" .
val res2 = IO.raiseError(new Exception("First Error")) <+> IO { "Second" }
res2.unsafeRunSync() // res2: "Second"
49
SemigroupK - Option
Option || .
.
Some .
1.some <+> none // Some(1)
!
1.some <+> 2.some // Some(1)
!
none <+> 2.some // Some(2)
"
50
SemigroupK Cache miss
def fetch[F[_]](id: Int)(implicit F: Effect[F]): F[Option[User]] =
fetchLocalCache(id).flatMap { //local cache
case cached @ Some(_) => F.pure(cached) //
case None => //
fetchRemoteCache(id).flatMap { //remote cache
case cached @ Some(_) => F.pure(cached)// .
case None => fetchDB(id) // DB .
}
}
51
SemigroupK Cache miss
.
!
FP !!!
def fetch[F[_]: Effect](id: Int): F[Option[User]] = (
OptionT(fetchLocalCache(id)) <+>
OptionT(fetchRemoteCache(id)) <+>
OptionT(fetchDB(id))
).value
cache layer
cache layer .
52
1.
2.
3. cache
4. nullable
53
4. nullable
Problem
API null
Future[Option[A]] .
— DB select one
— Cache get
— Http request
Future Option ...
monadic .. ?
54
4. Future[Option[A]]
order -> user -> address .
Future[Option[A]] for .
for {
orderOption <- findOrder(orderId)
userOption <- orderOption match {
case Some(order) => findUser(order.userId)
case None => Future.successful(None)
}
address <- userOption match {
case Some(user) => findAddress(user.id)
case None => Future.successful(None)
}
} yield address
55
4. Monad Transformer Save Us
Monad Transformer .
.
!
cats
Monad Transformer datatype .
56
github ...
Monad transformer ... 19
Monad Transformer ...
Monad Transformer .
19
https://github.com/ikhoon/scala-note/blob/master/scala-exercise/src/test/scala/catsnote/
MonadTransformerSaveUs.scala
57
Monad Transformer ?
Monad .
Monad
flatMap .
!
Monad Tranformer
Monad
.
Monad
Scala with Cats15
5 .
!
15
https://underscore.io/training/courses/advanced-
scala/
58
Monad Transformer
WriterT, StateT Monad Transformer OptionT EitherT
.(flatMap )
OptionT = monad tranformer for Option 5
OptionT[F[_], A] is a light wrapper on an F[Option[A]]
EitherT = monad tranformer for Either 6
EitherT[F[_], A, B] is a light wrapper for F[Either[A, B]]
6
https://typelevel.org/cats/datatypes/eithert.html
5
https://typelevel.org/cats/datatypes/optiont.html
59
- OptionT
flatMap A => F[Option[A]] Option[A] => F[Option[B]] .
case class OptionT[F[_], A](value: F[Option[A]]) {
def flatMapF[B](f: A => F[Option[B]])(implicit F: Monad[F]): OptionT[F, B] = {
/* : F.flatMap Option[A] => F[Option[B]] .
f A => F[Option[B] .
: Option fn
f Option[A] => F[Option[B]] . */
def fn(fa: Option[A]): F[Option[B]] = fa match {
case Some(v) => f(v)
case None => F.pure[Option[B]](None)
}
OptionT(F.flatMap(value)(fn))
}
def flatMap[B](f: A => OptionT[F, B])(implicit F: Monad[F]): OptionT[F, B] =
flatMapF(a => f(a).value)
}
60
- F[Option[A]] OptionT
OptinonT
for {
orderOption <- findOrder(orderId)
userOption <- orderOption match {
case Some(order) => findUser(order.userId)
case None => Future.successful(None)
}
addr <- userOption match {
case Some(user) => findAddress(user.id)
case None => Future.successful(None)
}
} yield addr
61
- F[Option[A]] OptionT
.
!
FP !!!
val address = for {
order <- OptionT(findOrder(orderId))
user <- OptionT(findUser(order.userId))
addr <- OptionT(findAddress(user.id))
} yield addr
62
- Future[Option[A]]
A, Option[A], Future[A], Future[Option[A]]
real world .
.
!
.
lift OptionT .
def getUserDevice(userId: String): Future[Option[Device]] = {
val userId = parseUserId(userId) // Option[Long]
val user = findUser(userId) // Future[Option[User]]
val phoneNumber = getPhoneNumber(user) // String
val device = findDevice(phoneNumber) // Future[Device]
device
}
63
- OptionT
- A => Future[Option[B]] ? OptionT !
- A => Option[C] ? OptionT.fromOption[Future] .
- A => D ? OptionT.pure[Future, A] !
- A => Future[E] ? OptionT.liftF .
- Future[Option[A]] !!!!
def findDeviceByUserId(userId: String): Future[Option[Device]] = (for {
userId <- OptionT.fromOption[Future](parseUserId(userId)) // Option[Long]
user <- OptionT(findUser(userId)) // Future[Option[User]]
phone <- OptionT.pure[Future](getPhoneNumber(user)) // String
device <- OptionT.liftF(findDevice(phone)) // Future[Device]
} yield device).value
64
.
!"
Learning resources
— https://typelevel.org/cats/
,
— https://www.scala-exercises.org/cats
— http://eed3si9n.com/herding-cats
— https://underscore.io/training/courses/advanced-scala/
— ( ) #
65
BACKUP SLIDE
66
-
Typeclass API
+
67
Monoid 7
( : monoid)
,
.
,
.
7
https://ko.wikipedia.org/wiki/
%EB%AA%A8%EB%85%B8%EC%9D%B4%EB%93%9C
68
API
map, flatMap
Monad instance monadic
Option, List, Future datatype
map flatMap .
pure, handleError
.
- monad (pure)
- (handleError)
API .
.
69
API
data type
scala future successful failed recover
twitter future value exception handle
monix task pure onErrorRecover raiseError
.
.
API .
! ! !
70
API
71
72
API
73
cats typeclass
— scala.cocurent.Future
— com.twitter.util.Future
— monix.eval.Task
— cats.effect.IO
API .
74
, scala Future API .
def getItem(id: Long): ScalaFuture[Either[Throwable, ItemDto]] =
if(id < 0) ScalaFuture.successful(
Left(new IllegalArgumentException(s" ID . $id")))
else
itemRepository.findById(id)
.flatMap(item =>
optionRepository.findByItemId(item.id)
.map(option =>
Right(ItemDto(item.id, item.name, option))
.recover { case ex: Throwable => Left(ex)}
75
cats API
def getItem[F[_]](id: Long)
(implicit F: MonadError[F, Throwable]): F[Either[Throwable, ItemDto]] =
if(id < 0) F.pure(
Left(new IllegalArgumentException(s" ID . $id")))
else
itemRepository[F].findById(id)
.flatMap(item =>
optionRepository[F].findByItemId(item.id)
.map(option =>
Either.right[Throwable, ItemDto](ItemDto(item.id, item.name, option))))
.handleError(ex => Left(ex))
pure, flatMap, map, handleError
cats api .
76
Effect
MonadError instance
monadic data type .
// before - only scala future
def getItem(id: Long): ScalaFuture[Either[Throwable, ItemDto]]
// after
def getItem[F[_]]
(id: Long)(implicit F: MonadError[F, Throwable])
: F[Either[Throwable, ItemDto]]
// getItem .
// ScalaFuture, TwitterFuture MonixTask cats api .
val scalaFuture = getItem[ScalaFuture](10)
val twiiterFuture = getItem[TwitterFuture](10)
val monixTask = getItem[MonixTask](10)
77
API
CompletableFuture
...
// java completable future
val a = CompletableFuture.completedFuture(10)
// map
val b: CompletableFuture[Int] = a.thenApply(x => x + 10)
// flatMap
val c = b.thenCompose(x => CompletableFuture.completedFuture(x * 10))
78
.
thenApply, thenCompose .
79
- Monad instance
// CompletableFuture instance .
implicit val futureInstance = new Monad[CompletableFuture]
with StackSafeMonad[CompletableFuture] {
def pure[A](x: A): CompletableFuture[A] =
CompletableFuture.completedFuture(x)
def flatMap[A, B]
(fa: CompletableFuture[A])
(f: A => CompletableFuture[B]): CompletableFuture[B] =
fa.thenCompose(f.asJava)
}
80
Native API vs Cats API
.
// Java completable future
val a = CompletableFuture.completedFuture(10)
val b = a.thenApply(x => x + 10)
val c = b.thenCompose(x => CompletableFuture.completedFuture(x * 10))
// Cats monad api
val a2 = 10.pure[CompletableFuture]
val b2 = a2.map(x => x + 10)
val c2 = b2.flatMap(x => (x * 10).pure[CompletableFuture])
81
Real World Cats
.
Future, HashMap, HttpServer .
API .
Cats API .
82
(2015) ...12
12
https://github.com/typelevel/cats/issues/95#issuecomment-114023955
83
Cats - Typeclass
.
!
Functor Monad .
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
trait Monad[F[_]] {
def pure[A](a: A): F[A]
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
}
84
Cats - Data types
.
!
OptionT EitherT .
— OptionT = monad tranformer for Option 5
OptionT[F[_], A] is a light wrapper on an F[Option[A]]
— EitherT = monad tranformer for Either 6
EitherT[F[_], A, B] is a lightweight wrapper for F[Either[A, B]]
6
https://typelevel.org/cats/datatypes/eithert.html
5
https://typelevel.org/cats/datatypes/optiont.html
85
Cats - Instance
scala stdlib data type cats typeclass instance
// .../cats/instances/all.scala
trait AllInstances
xtends AnyValInstances
with ...
with ListInstances
with MapInstances
with OptionInstances
with OrderInstances
with OrderingInstances
with TupleInstances
with UUIDInstances
with VectorInstances
with ...
cats data type instance
86
Do It Yourself !
monad
transformer
cats
!
2016 9 25
monad transformer
...20
20
http://loicdescotte.github.io/posts/scala-compose-
option-future/
87
Monad Transformer
— .
— lift .
— Future[Option[A]] OptionT
.
88
3. - Monad Tranformer ?
Monad compose Monad .
Applicative .22
trait Applicative[F[_]] {
def compose[G[_]: Applicative]: Applicative[λ[α => F[G[α]]]] =
new ComposedApplicative[F, G] {
val F = self
val G = Applicative[G]
}
}
Monad[Future].compose[Option] // Applicative[Future[Option[α]]]
22
https://github.com/typelevel/cats/blob/2ae785f726b810438fa5b429d5c9d28f1be2e69d/core/
src/main/scala/cats/Applicative.scala#L88-L92
89
3. - Monad Tranformer ?
Future[Option[A]]
Monad
Monad Transformer
.21
21
http://book.realworldhaskell.org/read/monad-transformers.html
90
Cats Monad
50 XXX2~22 60 110 .
// scala reflection
import scala.reflect.runtime.universe._
typeOf[Monad[Future]].members.map(show(_))
//
widen, whileM_, whileM, whenA, void, untilM_,
untilM, unlessA, unit, tupleRight, tupleLeft,
replicateA, product, productREval, productR,
productLEval, productL, point, mproduct, map, lift,
iterateWhileM, iterateWhile, iterateUntilM,
iterateUntil, imap, ifM, fproduct, forEffect,
forEffectEval,followedBy, followedByEval, fmap,
flatten, flatTap, compose, composeFunctor,
composeContravariant, composeContravariantMonoidal,
composeApply, as, ap, <*, <*>, *>,
tuple2~22, map2Eval, map2~22, ap2~22
91
cache miss
import cats.effect.Effect
// local cache
def fetchLocalCache[F[_]] (key: Int)(implicit F: Effect[F]): F[Option[User]]
// remote cache
def fetchRemoteCache[F[_]](key: Int)(implicit F: Effect[F]): F[Option[User]]
// persistence db
def fetchDB[F[_]] (key: Int)(implicit F: Effect[F]): F[Option[User]]
92
93

Más contenido relacionado

La actualidad más candente

Python Performance 101
Python Performance 101Python Performance 101
Python Performance 101Ankur Gupta
 
Google Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & AndroidGoogle Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & AndroidJordi Gerona
 
Profiling and optimization
Profiling and optimizationProfiling and optimization
Profiling and optimizationg3_nittala
 
sizeof(Object): how much memory objects take on JVMs and when this may matter
sizeof(Object): how much memory objects take on JVMs and when this may mattersizeof(Object): how much memory objects take on JVMs and when this may matter
sizeof(Object): how much memory objects take on JVMs and when this may matterDawid Weiss
 
The Language for future-julia
The Language for future-juliaThe Language for future-julia
The Language for future-julia岳華 杜
 
响应式编程及框架
响应式编程及框架响应式编程及框架
响应式编程及框架jeffz
 
Python na Infraestrutura 
MySQL do Facebook

Python na Infraestrutura 
MySQL do Facebook
Python na Infraestrutura 
MySQL do Facebook

Python na Infraestrutura 
MySQL do Facebook
Artur Rodrigues
 
Euro python2011 High Performance Python
Euro python2011 High Performance PythonEuro python2011 High Performance Python
Euro python2011 High Performance PythonIan Ozsvald
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them AllJohn De Goes
 
Odessapy2013 - Graph databases and Python
Odessapy2013 - Graph databases and PythonOdessapy2013 - Graph databases and Python
Odessapy2013 - Graph databases and PythonMax Klymyshyn
 
Google guava overview
Google guava overviewGoogle guava overview
Google guava overviewSteve Min
 
Lab report for Prolog program in artificial intelligence.
Lab report for Prolog program in artificial intelligence.Lab report for Prolog program in artificial intelligence.
Lab report for Prolog program in artificial intelligence.Alamgir Hossain
 
Fun never stops. introduction to haskell programming language
Fun never stops. introduction to haskell programming languageFun never stops. introduction to haskell programming language
Fun never stops. introduction to haskell programming languagePawel Szulc
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsMichael Pirnat
 
The Ring programming language version 1.5.3 book - Part 10 of 184
The Ring programming language version 1.5.3 book - Part 10 of 184The Ring programming language version 1.5.3 book - Part 10 of 184
The Ring programming language version 1.5.3 book - Part 10 of 184Mahmoud Samir Fayed
 
Python part2 v1
Python part2 v1Python part2 v1
Python part2 v1Sunil OS
 
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...Charles Nutter
 

La actualidad más candente (20)

Python Performance 101
Python Performance 101Python Performance 101
Python Performance 101
 
Google Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & AndroidGoogle Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & Android
 
Google Guava
Google GuavaGoogle Guava
Google Guava
 
Profiling and optimization
Profiling and optimizationProfiling and optimization
Profiling and optimization
 
sizeof(Object): how much memory objects take on JVMs and when this may matter
sizeof(Object): how much memory objects take on JVMs and when this may mattersizeof(Object): how much memory objects take on JVMs and when this may matter
sizeof(Object): how much memory objects take on JVMs and when this may matter
 
The Language for future-julia
The Language for future-juliaThe Language for future-julia
The Language for future-julia
 
响应式编程及框架
响应式编程及框架响应式编程及框架
响应式编程及框架
 
Python na Infraestrutura 
MySQL do Facebook

Python na Infraestrutura 
MySQL do Facebook
Python na Infraestrutura 
MySQL do Facebook

Python na Infraestrutura 
MySQL do Facebook

 
Euro python2011 High Performance Python
Euro python2011 High Performance PythonEuro python2011 High Performance Python
Euro python2011 High Performance Python
 
Java Class Design
Java Class DesignJava Class Design
Java Class Design
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them All
 
Odessapy2013 - Graph databases and Python
Odessapy2013 - Graph databases and PythonOdessapy2013 - Graph databases and Python
Odessapy2013 - Graph databases and Python
 
Google guava overview
Google guava overviewGoogle guava overview
Google guava overview
 
Lab report for Prolog program in artificial intelligence.
Lab report for Prolog program in artificial intelligence.Lab report for Prolog program in artificial intelligence.
Lab report for Prolog program in artificial intelligence.
 
Fun never stops. introduction to haskell programming language
Fun never stops. introduction to haskell programming languageFun never stops. introduction to haskell programming language
Fun never stops. introduction to haskell programming language
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) Things
 
The Ring programming language version 1.5.3 book - Part 10 of 184
The Ring programming language version 1.5.3 book - Part 10 of 184The Ring programming language version 1.5.3 book - Part 10 of 184
The Ring programming language version 1.5.3 book - Part 10 of 184
 
Python part2 v1
Python part2 v1Python part2 v1
Python part2 v1
 
MTL Versus Free
MTL Versus FreeMTL Versus Free
MTL Versus Free
 
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
 

Similar a Real world cats

Python 2.5 reference card (2009)
Python 2.5 reference card (2009)Python 2.5 reference card (2009)
Python 2.5 reference card (2009)gekiaruj
 
Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)stasimus
 
Functional Programming inside OOP? It’s possible with Python
Functional Programming inside OOP? It’s possible with PythonFunctional Programming inside OOP? It’s possible with Python
Functional Programming inside OOP? It’s possible with PythonCarlos V.
 
T3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmerT3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmerDavid Muñoz Díaz
 
java 8 Hands on Workshop
java 8 Hands on Workshopjava 8 Hands on Workshop
java 8 Hands on WorkshopJeanne Boyarsky
 
Machine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting ConcernsMachine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting Concernssaintiss
 
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015Michiel Borkent
 
Attacking the macOS Kernel Graphics Driver
Attacking the macOS Kernel Graphics DriverAttacking the macOS Kernel Graphics Driver
Attacking the macOS Kernel Graphics DriverPriyanka Aash
 
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPythonByterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPythonakaptur
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)David de Boer
 
The secrets of inverse brogramming
The secrets of inverse brogrammingThe secrets of inverse brogramming
The secrets of inverse brogrammingRichie Cotton
 
Python 내장 함수
Python 내장 함수Python 내장 함수
Python 내장 함수용 최
 
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedPascal-Louis Perez
 
Google Go For Ruby Hackers
Google Go For Ruby HackersGoogle Go For Ruby Hackers
Google Go For Ruby HackersEleanor McHugh
 
BASE Meetup: "Analysing Scala Puzzlers: Essential and Accidental Complexity i...
BASE Meetup: "Analysing Scala Puzzlers: Essential and Accidental Complexity i...BASE Meetup: "Analysing Scala Puzzlers: Essential and Accidental Complexity i...
BASE Meetup: "Analysing Scala Puzzlers: Essential and Accidental Complexity i...Andrew Phillips
 
Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexit...
Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexit...Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexit...
Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexit...Andrew Phillips
 
Bytes in the Machine: Inside the CPython interpreter
Bytes in the Machine: Inside the CPython interpreterBytes in the Machine: Inside the CPython interpreter
Bytes in the Machine: Inside the CPython interpreterakaptur
 

Similar a Real world cats (20)

Python 2.5 reference card (2009)
Python 2.5 reference card (2009)Python 2.5 reference card (2009)
Python 2.5 reference card (2009)
 
Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)
 
Functional Programming inside OOP? It’s possible with Python
Functional Programming inside OOP? It’s possible with PythonFunctional Programming inside OOP? It’s possible with Python
Functional Programming inside OOP? It’s possible with Python
 
T3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmerT3chFest 2016 - The polyglot programmer
T3chFest 2016 - The polyglot programmer
 
java 8 Hands on Workshop
java 8 Hands on Workshopjava 8 Hands on Workshop
java 8 Hands on Workshop
 
Machine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting ConcernsMachine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting Concerns
 
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015
 
Attacking the macOS Kernel Graphics Driver
Attacking the macOS Kernel Graphics DriverAttacking the macOS Kernel Graphics Driver
Attacking the macOS Kernel Graphics Driver
 
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPythonByterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)
 
Intro to Python
Intro to PythonIntro to Python
Intro to Python
 
The secrets of inverse brogramming
The secrets of inverse brogrammingThe secrets of inverse brogramming
The secrets of inverse brogramming
 
Java VS Python
Java VS PythonJava VS Python
Java VS Python
 
Python 내장 함수
Python 내장 함수Python 내장 함수
Python 내장 함수
 
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing Speed
 
Google Go For Ruby Hackers
Google Go For Ruby HackersGoogle Go For Ruby Hackers
Google Go For Ruby Hackers
 
PythonOOP
PythonOOPPythonOOP
PythonOOP
 
BASE Meetup: "Analysing Scala Puzzlers: Essential and Accidental Complexity i...
BASE Meetup: "Analysing Scala Puzzlers: Essential and Accidental Complexity i...BASE Meetup: "Analysing Scala Puzzlers: Essential and Accidental Complexity i...
BASE Meetup: "Analysing Scala Puzzlers: Essential and Accidental Complexity i...
 
Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexit...
Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexit...Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexit...
Scala Up North: "Analysing Scala Puzzlers: Essential and Accidental Complexit...
 
Bytes in the Machine: Inside the CPython interpreter
Bytes in the Machine: Inside the CPython interpreterBytes in the Machine: Inside the CPython interpreter
Bytes in the Machine: Inside the CPython interpreter
 

Último

Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldRoberto Pérez Alcolea
 
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jGraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jNeo4j
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...Bert Jan Schrijver
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdfAndrey Devyatkin
 
Patterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencePatterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencessuser9e7c64
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolsosttopstonverter
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonApplitools
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptxVinzoCenzo
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...OnePlan Solutions
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorTier1 app
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogueitservices996
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?Alexandre Beguel
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesKrzysztofKkol1
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics
 

Último (20)

Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository world
 
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jGraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
 
Patterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencePatterns for automating API delivery. API conference
Patterns for automating API delivery. API conference
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration tools
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptx
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryError
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogue
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
 

Real world cats

  • 2. ! - , (~ 2015) ! - ? (2016) Category theory ! - ... ! (2017) Pure functional ! - (2018 ~) ... 2
  • 3. , y = f(x) 1. ? 3
  • 4. , y = f(x) 1. ? : 3, 4 " ." 29 29 https://ko.wikipedia.org/wiki/ %ED%95%A8%EC%88%98#%EB%B6%80%EB%B6%84_%EC%A0%95%EC%9D% 98_%ED%95%A8%EC%88%98_%C2%B7_%EB%8B%A4%EA%B0%80_%ED%95 %A8%EC%88%98 4
  • 5. , y = f(x) ? 2. ? 5
  • 7. def factorial(n: Int): Either[String, BigInt] = if (n < 0) Left("n 0 ") else if (n == 0) Right(1) else factorial(n - 1).map(_ * n) cats . Either Monadic cats ;-) 7
  • 8. + 8
  • 9. 2 — They’re easier to reason about — They’re easier to combine — They’re easier to test — They’re easier to debug — They’re easier to parallelize — They are idempotent — They offer referential transparency — They are memoizable — They can be lazy 2 Book, Functional Programming Simplified - Alvin Alexander 9
  • 10. — . (compose), (parallel) (memoize), (lazy) . — DRY(Don't Repeat Yourself) 10
  • 11. ? 1 - ? — — Scala with Cats15 — , "scala cats" 458,000 15 https://underscore.io/training/courses/advanced-scala/ 11
  • 12. ? 2 - ? — 209 — 3452 — Pull Request 1524 (42 Open, 1482 Closed) — 1.0.0 . 12
  • 13. ? 3 - ecosystem ? — circe: pure functional JSON library — doobie: a pure functional JDBC layer for Scala — finch: Scala combinator library for building Finagle HTTP services — FS2: compositional, streaming I/O library — h!p4s: A minimal, idiomatic Scala interface for HTTP — Monix: high-performance library for composing asynchronous and event- based programs 31 . 13
  • 15. Cats — Typeclass .17 — Datatype ' A' typeclass instance ' A' typeclass . — ex) Option(datatype) Monad(typeclass) (instance) (pure, flatMap) . 17 http://learnyouahaskell.com/types-and-typeclasses 15
  • 16. Cats — Type classes 30 — Data types — Instance 30 https://github.com/tpolecat/cats-infographic 16
  • 17. Cats — Type classes — Data types — Instance . ! Core . . 17
  • 18. Cats — Type classes — Data types — Instance 18
  • 19. Cats — Type classes — Data types — Instance cats . OptionT EitherT !! . 19
  • 20. Cats — Type classes — Data types — Instance Instance Datatype typeclass . Data type type class . . core datatype core typeclass instance .18 18 https://typelevel.org/cats/typeclasses.html#incomplete-type-class-instances-in-cats 20
  • 21. Cats - Monad ? Monad . Monad ? 21
  • 22. Monad 8 C . C -> C , End(C) . End(C) , End(C) . End(C) C . 8 https://ko.wikipedia.org/wiki/ %EB%AA%A8%EB%82%98%EB%93%9C_(%EB%B2%94% EC%A3%BC%EB%A1%A0) 22
  • 23. Cats - Monad ? Monad . ? flatMap(Monad) . 23
  • 24. Cats - Ordered compare 4 (<, <=, >, >=) . case class Version(major: Int, minor: Int, patch: Int) extends Ordered[Version] { def compare(that: Version): Int = if(major > that.major) 1 else if (major == that.major && minor > that.minor) 1 ... else -1 } Version(1, 11, 1) < Version(1, 1, 1) // false Version(1, 10, 1) > Version(0, 0, 1) // true Version(10, 9, 3) <= Version(0, 0, 1) // false 24
  • 25. Monad . pure flatMap ! .( 110 ) — map = pure + flatMap — ap = flatMap + map — product = map + ap — map2 = map + product 25
  • 26. Monad . def map[A, B](fa: F[A])(f: A => B): F[B] = flatMap(fa)(f andThen pure) def ap[A, B](fa: F[A])(ff: F[A => B]): F[B] = flatMap(fa)(a => map(ff)(f => f(a))) def product[A, B](fa: F[A], fb: F[B]): F[(A, B)] = ap(fb)(map(fa)(a => (b: B) => (a, b))) def map2[A, B, Z](fa: F[A], fb: F[B])(f: (A, B) => Z): F[Z] = map(product(fa, fb))(f.tupled) 26
  • 27. cats ... ... ! " backup slide " Cats 27
  • 29. 1. ! 100 . REST API API 100 API ... GET /v1/api/items/:id API 100 . val itemIds: List[Int] // API def findItemById(itemId: Int): Future[Option[Item]] 29
  • 30. API Problem API 100ms ? 100 10 ?! . ! API ... 2 . ! ! 30
  • 31. Solution 25 100 . 100 DDOS . . 100 10 10 . 1 . ! 25 Reactive Microservices Architecture By Jonas Bonér, Co-Founder & CTO Lightbend, Inc. 31
  • 32. flatMap . traverse (map) (reduce) . flatMap traverse . def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] def traverse[G[_]: Applicative, A, B](fa: F[A])(f: A => G[B]): G[F[B]] 32
  • 33. Future, Lazy, Parallel traverse — Traverse Traverse typeclass . travese . — Parallel (parTraverse, parMapN) cats typeclass . Scala Future Parallel instance .28 — Scala Future (Eager) Eager evalution traverse . — Monix Task (Lazy) Lazy evaluation traverse . monix Task parTraverse . Monix Task . def findItemById(itemId: Int): Task[Item] // Monix Task itemIds.traverse(findItemById) // 10 itemIds.parTraverse(findItemById) // 1 28 https://www.reddit.com/r/scala/comments/7qimqg/cats_parallel_future_traverse/ 33
  • 34. 10 , 10 API - grouped : 10 - foldLeft : List - flatMap : 10 10 - traverse : 10 .( parTraverse) ! val items = itemIds .grouped(10).toList // .foldLeft(List.empty[Item].pure[Future]) ((acc, group) => acc.flatMap(xs => // group.traverse(findItemById).map(xs ::: _))) // 34
  • 36. 2. Problem ID ID . . val itemIds: List[Int] // API def isActiveItem[F[_]](itemId: Int)(implicit F: Effect[F]): F[Boolean] filter + async 36
  • 37. 2. ( ) . // 1. map . val step1: List[IO[(Int, Boolean)]] = itemIds.map(itemId => isActiveItem[IO](itemId).tupleLeft(itemId)) // 2. IO List val step2: IO[List[(Int, Boolean)]] = step1.sequence // 3. filter . val step3: IO[List[(Int, Boolean)]] = step2.map(xs => xs.filter(_._2)) // 4. Boolean val step4: IO[List[Int]] = step3.map(_.map(_._1)) 37
  • 40. filterA . . filterA . import cats.mtl.implicits._ // filterA . val activeItem: IO[List[Int]] = itemIds.filterA(isActiveItem[IO]) 4 step filterA . . ! FP !!! . 40
  • 41. filterA def filterA[G[_], A] (fa: F[A])(f: A => G[Boolean]) (implicit G: Applicative[G]): G[F[A]] — filterA predicate A => G[Boolean] . — G Applicative Applicative instance List, Future, Option . — filterA . f: A => Option[Boolean] . 41
  • 42. cats 1.x filterA cats 0.x filterA import import cats.implicits._ // 0.x cats 1.x filterA cats-mtl23 . import . libraryDependencies += "org.typelevel" %% "cats-mtl" % "0.2.1" import cats.mtl.implicits._ // import 23 https://github.com/typelevel/cats-mtl/blob/f3bd9aa4c8c0466d8cb4aa25bfcc6480531929c5/ core/src/main/scala/cats/mtl/TraverseEmpty.scala#L48 42
  • 44. 3. cache ! cache . Cache miss backup . Problem - . . . . cache layer . def fetch[F[_]](id: Int)(implicit F: Effect[F]): F[Option[User]] = fetchLocalCache(id).flatMap { //local cache case cached @ Some(_) => F.pure(cached) // case None => // fetchRemoteCache(id).flatMap { //remote cache case cached @ Some(_) => F.pure(cached)// . case None => fetchDB(id) // DB . } } 44
  • 45. Problem - . def fetch[F[_]](id: Int)(implicit F: Effect[F]): F[Option[User]] = fetchLocalCache(id).flatMap { // local cache case cached @ Some(_) => F.pure(cached) // case None => // fetchRemoteCache(id).flatMap { // remote cache case cached @ Some(_) => F.pure(cached) // . case None => fetchDB(id) // DB . } } 45
  • 47. Cache miss cache layer (pattern) ? ! !!! SemigroupK “pick the first winner” 10 . 10 Book, Functional Programming for Mortals with Scalaz - Sam Halliday 47
  • 48. SemigroupK - . F[A] @typeclass trait SemigroupK[F[_]] { @op("<+>") def combineK[A](x: F[A], y: F[A]): F[A] } - Plus (or as cats have renamed it, SemigroupK) has "pick the first winner, ignore errors" semantics. Although it is not expressed in its laws.11 11 https://github.com/typelevel/cats-effect/issues/94#issuecomment-351736393 48
  • 49. SemigroupK - IO IO . . // "First" . IO.apply lazy . val res1 = IO { "First" } <+> IO { "Second" } res1.unsafeRunSync() // res1: "First" // "First Error" ! "Second" . val res2 = IO.raiseError(new Exception("First Error")) <+> IO { "Second" } res2.unsafeRunSync() // res2: "Second" 49
  • 50. SemigroupK - Option Option || . . Some . 1.some <+> none // Some(1) ! 1.some <+> 2.some // Some(1) ! none <+> 2.some // Some(2) " 50
  • 51. SemigroupK Cache miss def fetch[F[_]](id: Int)(implicit F: Effect[F]): F[Option[User]] = fetchLocalCache(id).flatMap { //local cache case cached @ Some(_) => F.pure(cached) // case None => // fetchRemoteCache(id).flatMap { //remote cache case cached @ Some(_) => F.pure(cached)// . case None => fetchDB(id) // DB . } } 51
  • 52. SemigroupK Cache miss . ! FP !!! def fetch[F[_]: Effect](id: Int): F[Option[User]] = ( OptionT(fetchLocalCache(id)) <+> OptionT(fetchRemoteCache(id)) <+> OptionT(fetchDB(id)) ).value cache layer cache layer . 52
  • 54. 4. nullable Problem API null Future[Option[A]] . — DB select one — Cache get — Http request Future Option ... monadic .. ? 54
  • 55. 4. Future[Option[A]] order -> user -> address . Future[Option[A]] for . for { orderOption <- findOrder(orderId) userOption <- orderOption match { case Some(order) => findUser(order.userId) case None => Future.successful(None) } address <- userOption match { case Some(user) => findAddress(user.id) case None => Future.successful(None) } } yield address 55
  • 56. 4. Monad Transformer Save Us Monad Transformer . . ! cats Monad Transformer datatype . 56
  • 57. github ... Monad transformer ... 19 Monad Transformer ... Monad Transformer . 19 https://github.com/ikhoon/scala-note/blob/master/scala-exercise/src/test/scala/catsnote/ MonadTransformerSaveUs.scala 57
  • 58. Monad Transformer ? Monad . Monad flatMap . ! Monad Tranformer Monad . Monad Scala with Cats15 5 . ! 15 https://underscore.io/training/courses/advanced- scala/ 58
  • 59. Monad Transformer WriterT, StateT Monad Transformer OptionT EitherT .(flatMap ) OptionT = monad tranformer for Option 5 OptionT[F[_], A] is a light wrapper on an F[Option[A]] EitherT = monad tranformer for Either 6 EitherT[F[_], A, B] is a light wrapper for F[Either[A, B]] 6 https://typelevel.org/cats/datatypes/eithert.html 5 https://typelevel.org/cats/datatypes/optiont.html 59
  • 60. - OptionT flatMap A => F[Option[A]] Option[A] => F[Option[B]] . case class OptionT[F[_], A](value: F[Option[A]]) { def flatMapF[B](f: A => F[Option[B]])(implicit F: Monad[F]): OptionT[F, B] = { /* : F.flatMap Option[A] => F[Option[B]] . f A => F[Option[B] . : Option fn f Option[A] => F[Option[B]] . */ def fn(fa: Option[A]): F[Option[B]] = fa match { case Some(v) => f(v) case None => F.pure[Option[B]](None) } OptionT(F.flatMap(value)(fn)) } def flatMap[B](f: A => OptionT[F, B])(implicit F: Monad[F]): OptionT[F, B] = flatMapF(a => f(a).value) } 60
  • 61. - F[Option[A]] OptionT OptinonT for { orderOption <- findOrder(orderId) userOption <- orderOption match { case Some(order) => findUser(order.userId) case None => Future.successful(None) } addr <- userOption match { case Some(user) => findAddress(user.id) case None => Future.successful(None) } } yield addr 61
  • 62. - F[Option[A]] OptionT . ! FP !!! val address = for { order <- OptionT(findOrder(orderId)) user <- OptionT(findUser(order.userId)) addr <- OptionT(findAddress(user.id)) } yield addr 62
  • 63. - Future[Option[A]] A, Option[A], Future[A], Future[Option[A]] real world . . ! . lift OptionT . def getUserDevice(userId: String): Future[Option[Device]] = { val userId = parseUserId(userId) // Option[Long] val user = findUser(userId) // Future[Option[User]] val phoneNumber = getPhoneNumber(user) // String val device = findDevice(phoneNumber) // Future[Device] device } 63
  • 64. - OptionT - A => Future[Option[B]] ? OptionT ! - A => Option[C] ? OptionT.fromOption[Future] . - A => D ? OptionT.pure[Future, A] ! - A => Future[E] ? OptionT.liftF . - Future[Option[A]] !!!! def findDeviceByUserId(userId: String): Future[Option[Device]] = (for { userId <- OptionT.fromOption[Future](parseUserId(userId)) // Option[Long] user <- OptionT(findUser(userId)) // Future[Option[User]] phone <- OptionT.pure[Future](getPhoneNumber(user)) // String device <- OptionT.liftF(findDevice(phone)) // Future[Device] } yield device).value 64
  • 65. . !" Learning resources — https://typelevel.org/cats/ , — https://www.scala-exercises.org/cats — http://eed3si9n.com/herding-cats — https://underscore.io/training/courses/advanced-scala/ — ( ) # 65
  • 68. Monoid 7 ( : monoid) , . , . 7 https://ko.wikipedia.org/wiki/ %EB%AA%A8%EB%85%B8%EC%9D%B4%EB%93%9C 68
  • 69. API map, flatMap Monad instance monadic Option, List, Future datatype map flatMap . pure, handleError . - monad (pure) - (handleError) API . . 69
  • 70. API data type scala future successful failed recover twitter future value exception handle monix task pure onErrorRecover raiseError . . API . ! ! ! 70
  • 72. 72
  • 74. cats typeclass — scala.cocurent.Future — com.twitter.util.Future — monix.eval.Task — cats.effect.IO API . 74
  • 75. , scala Future API . def getItem(id: Long): ScalaFuture[Either[Throwable, ItemDto]] = if(id < 0) ScalaFuture.successful( Left(new IllegalArgumentException(s" ID . $id"))) else itemRepository.findById(id) .flatMap(item => optionRepository.findByItemId(item.id) .map(option => Right(ItemDto(item.id, item.name, option)) .recover { case ex: Throwable => Left(ex)} 75
  • 76. cats API def getItem[F[_]](id: Long) (implicit F: MonadError[F, Throwable]): F[Either[Throwable, ItemDto]] = if(id < 0) F.pure( Left(new IllegalArgumentException(s" ID . $id"))) else itemRepository[F].findById(id) .flatMap(item => optionRepository[F].findByItemId(item.id) .map(option => Either.right[Throwable, ItemDto](ItemDto(item.id, item.name, option)))) .handleError(ex => Left(ex)) pure, flatMap, map, handleError cats api . 76
  • 77. Effect MonadError instance monadic data type . // before - only scala future def getItem(id: Long): ScalaFuture[Either[Throwable, ItemDto]] // after def getItem[F[_]] (id: Long)(implicit F: MonadError[F, Throwable]) : F[Either[Throwable, ItemDto]] // getItem . // ScalaFuture, TwitterFuture MonixTask cats api . val scalaFuture = getItem[ScalaFuture](10) val twiiterFuture = getItem[TwitterFuture](10) val monixTask = getItem[MonixTask](10) 77
  • 78. API CompletableFuture ... // java completable future val a = CompletableFuture.completedFuture(10) // map val b: CompletableFuture[Int] = a.thenApply(x => x + 10) // flatMap val c = b.thenCompose(x => CompletableFuture.completedFuture(x * 10)) 78
  • 80. - Monad instance // CompletableFuture instance . implicit val futureInstance = new Monad[CompletableFuture] with StackSafeMonad[CompletableFuture] { def pure[A](x: A): CompletableFuture[A] = CompletableFuture.completedFuture(x) def flatMap[A, B] (fa: CompletableFuture[A]) (f: A => CompletableFuture[B]): CompletableFuture[B] = fa.thenCompose(f.asJava) } 80
  • 81. Native API vs Cats API . // Java completable future val a = CompletableFuture.completedFuture(10) val b = a.thenApply(x => x + 10) val c = b.thenCompose(x => CompletableFuture.completedFuture(x * 10)) // Cats monad api val a2 = 10.pure[CompletableFuture] val b2 = a2.map(x => x + 10) val c2 = b2.flatMap(x => (x * 10).pure[CompletableFuture]) 81
  • 82. Real World Cats . Future, HashMap, HttpServer . API . Cats API . 82
  • 84. Cats - Typeclass . ! Functor Monad . trait Functor[F[_]] { def map[A, B](fa: F[A])(f: A => B): F[B] } trait Monad[F[_]] { def pure[A](a: A): F[A] def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] } 84
  • 85. Cats - Data types . ! OptionT EitherT . — OptionT = monad tranformer for Option 5 OptionT[F[_], A] is a light wrapper on an F[Option[A]] — EitherT = monad tranformer for Either 6 EitherT[F[_], A, B] is a lightweight wrapper for F[Either[A, B]] 6 https://typelevel.org/cats/datatypes/eithert.html 5 https://typelevel.org/cats/datatypes/optiont.html 85
  • 86. Cats - Instance scala stdlib data type cats typeclass instance // .../cats/instances/all.scala trait AllInstances xtends AnyValInstances with ... with ListInstances with MapInstances with OptionInstances with OrderInstances with OrderingInstances with TupleInstances with UUIDInstances with VectorInstances with ... cats data type instance 86
  • 87. Do It Yourself ! monad transformer cats ! 2016 9 25 monad transformer ...20 20 http://loicdescotte.github.io/posts/scala-compose- option-future/ 87
  • 88. Monad Transformer — . — lift . — Future[Option[A]] OptionT . 88
  • 89. 3. - Monad Tranformer ? Monad compose Monad . Applicative .22 trait Applicative[F[_]] { def compose[G[_]: Applicative]: Applicative[λ[α => F[G[α]]]] = new ComposedApplicative[F, G] { val F = self val G = Applicative[G] } } Monad[Future].compose[Option] // Applicative[Future[Option[α]]] 22 https://github.com/typelevel/cats/blob/2ae785f726b810438fa5b429d5c9d28f1be2e69d/core/ src/main/scala/cats/Applicative.scala#L88-L92 89
  • 90. 3. - Monad Tranformer ? Future[Option[A]] Monad Monad Transformer .21 21 http://book.realworldhaskell.org/read/monad-transformers.html 90
  • 91. Cats Monad 50 XXX2~22 60 110 . // scala reflection import scala.reflect.runtime.universe._ typeOf[Monad[Future]].members.map(show(_)) // widen, whileM_, whileM, whenA, void, untilM_, untilM, unlessA, unit, tupleRight, tupleLeft, replicateA, product, productREval, productR, productLEval, productL, point, mproduct, map, lift, iterateWhileM, iterateWhile, iterateUntilM, iterateUntil, imap, ifM, fproduct, forEffect, forEffectEval,followedBy, followedByEval, fmap, flatten, flatTap, compose, composeFunctor, composeContravariant, composeContravariantMonoidal, composeApply, as, ap, <*, <*>, *>, tuple2~22, map2Eval, map2~22, ap2~22 91
  • 92. cache miss import cats.effect.Effect // local cache def fetchLocalCache[F[_]] (key: Int)(implicit F: Effect[F]): F[Option[User]] // remote cache def fetchRemoteCache[F[_]](key: Int)(implicit F: Effect[F]): F[Option[User]] // persistence db def fetchDB[F[_]] (key: Int)(implicit F: Effect[F]): F[Option[User]] 92
  • 93. 93