SlideShare a Scribd company logo
1 of 93
Download to read offline
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

More Related Content

What's hot

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
 

What's hot (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 to 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 to 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
 

Recently uploaded

Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Software Coding for software engineering
Software Coding for software engineeringSoftware Coding for software engineering
Software Coding for software engineeringssuserb3a23b
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptrcbcrtm
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 

Recently uploaded (20)

Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Software Coding for software engineering
Software Coding for software engineeringSoftware Coding for software engineering
Software Coding for software engineering
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.ppt
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 

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