SlideShare a Scribd company logo
FUNCTIONALFUNCTIONAL
ERROR HANDLINGERROR HANDLING
WITH CATSWITH CATS
MARK CANLASMARK CANLAS ·· NE SCALA 2020NE SCALA 2020
Functional Error Handling with Cats
Functional Error Handling with Cats
Functional Error Handling with Cats
OPTIONOPTION[_][_]
TRYTRY[_][_]
EITHEREITHER[_, _][_, _]
FUNCTORFUNCTOR[_][_]
APPLICATIVEAPPLICATIVE[_][_]
MONADMONAD[_][_]
ERRORS ASERRORS AS DATADATA
Functional Error Handling with Cats
Functional Error Handling with Cats
PARSING STRINGSPARSING STRINGS
case class AncientRecord(
age: String,
name: String,
rateOfIncome: String
)
case class Citizen(
age: Int,
name: String,
rateOfIncome: Double
)
def parseRecord(rec: AncientRecord): Citizen
Functional Error Handling with Cats
PARSING FUNCTIONSPARSING FUNCTIONS
def parseAge(s: String)
def parseName(s: String)
def parseRate(s: String)
Functional Error Handling with Cats
AA =>  => FF[[BB]]
case class AncientRecord(
age: String,
name: String,
rateOfIncome: String
)
case class Citizen(
age: Int,
name: String,
rateOfIncome: Double
)
// fate of record not guaranteed, via F
def parseRecord(rec: AncientRecord): F[Citizen]
OptionOption[_][_]
def parseAge(s: String): Option[Int]
def parseName(s: String): Option[String]
def parseRate(s: String): Option[Double]
FOR COMPREHENSIONFOR COMPREHENSION
def parseRecord(rec: AncientRecord): Option[Citizen] =
for {
age <- parseAge(rec.age)
name <- parseName(rec.name)
rate <- parseRate(rec.rate)
} yield Citizen(age, name, rate)
PARSING WITH OPTIONPARSING WITH OPTION
def parseRecord(rec: AncientRecord): Option[Citizen] =
for {
age <- parseAge(rec.age) // Some[Int]
name <- parseName(rec.name) // Some[String]
rate <- parseRate(rec.rate) // Some[Double]
} yield
Citizen(age, name, rate) // Some[Citizen]
NOT ALL AVAILABLENOT ALL AVAILABLE
def parseRecord(rec: AncientRecord): Option[Citizen] =
for {
age <- parseAge(rec.age) // Some[Int]
name <- parseName(rec.name) // None
rate <- parseRate(rec.rate) // (does not run)
} yield
Citizen(age, name, rate) // None
FIRST ONE WINSFIRST ONE WINS
FIRST ERROR WINSFIRST ERROR WINS
Functional Error Handling with Cats
Functional Error Handling with Cats
Functional Error Handling with Cats
TryTry[_][_]
def parseAge(s: String): Try[Int]
def parseName(s: String): Try[String]
def parseRate(s: String): Try[Double]
PARSING WITH TRYPARSING WITH TRY
def parseRecord(rec: AncientRecord): Try[Citizen] =
for {
age <- parseAge(rec.age) // Success[Int]
name <- parseName(rec.name) // Failure[String]
rate <- parseRate(rec.rate) // (does not run)
} yield
Citizen(age, name, rate) // Failure[Citizen]
Functional Error Handling with Cats
Name Happy path Sad path
Option[_] Some[_] None
Try[_] Success[_] Failure[_]
Functional Error Handling with Cats
Functional Error Handling with Cats
ERROR ADTERROR ADT
sealed trait ParsingErr
case class UnreadableAge (s: String) extends ParsingErr
case class UnreadableName(s: String) extends ParsingErr
case class UnreadableRate(s: String) extends ParsingErr
Functional Error Handling with Cats
EitherEither[_, _][_, _]
def parseAge(s: String): Either[UnreadableAge, Int]
def parseName(s: String): Either[UnreadableName, String]
def parseRate(s: String): Either[UnreadableRate, Double]
PARSING WITH EITHERPARSING WITH EITHER
def parseRecord(rec: AncientRecord): Either[ParsingErr, Citizen] =
for {
age <- parseAge(rec.age) // Right[UnreadableAge, Int]
name <- parseName(rec.name) // Left[UnreadableName, String]
rate <- parseRate(rec.rate) // (does not run)
} yield
Citizen(age, name, rate) // Left[ParsingErr, Citizen]
Functional Error Handling with Cats
Name Happy path Sad path
Option[_] Some[_] None
Try[_] Success[_] Failure[_]
Either[E, _] Right[E, _] Left[E, _]
Functional Error Handling with Cats
def parseRecord(rec: AncientRecord): Either[ParsingErr, Citizen]
def parseRecord(rec: AncientRecord): Either[ParsingErr, Citizen]
sealed trait HttpResponse
case class HttpSucccess (s: String) extends HttpResponse
case class HttpClientError(s: String) extends HttpResponse
def present(res: Either[ParsingErr, Citizen]): HttpResponse
def parseRecord(rec: AncientRecord): Either[ParsingErr, Citizen]
sealed trait HttpResponse
case class HttpSucccess (s: String) extends HttpResponse
case class HttpClientError(s: String) extends HttpResponse
def present(res: Either[ParsingErr, Citizen]): HttpResponse
def httpError(err: ParsingError): HttpClientError
def httpSuccess(c: Citizen): HttpSucccess
USINGUSING .fold().fold()
val res: Either[ParsingErr, Citizen] = ???
val httpResponse: HttpResponse =
res
.fold(httpError, httpSuccess)
USINGUSING .leftMap().leftMap()
val res: Either[ParsingErr, Citizen] = ???
val httpResponse: HttpResponse =
res // Either[ParsingErr, Citizen]
.map(httpSuccess) // Either[ParsingErr, HttpSucccess]
.leftMap(httpError) // Either[HttpClientError, HttpSucccess]
.merge // HttpResponse
EitherEither[[EE, , AA]] BIFUNCTORBIFUNCTOR
Can map over E
Can map over A
POSTFIX SYNTAXPOSTFIX SYNTAX
import cats.implicits._
def luckyNumber: Either[String, Int] =
if (Random.nextBoolean)
42.asRight
else
"You are unlucky.".asLeft
Functional Error Handling with Cats
Functional Error Handling with Cats
IOIO[_][_]
def parseAge(s: String): IO[Int]
def parseName(s: String): IO[String]
def parseRate(s: String): IO[Double]
PARSING WITH IOPARSING WITH IO
def parseRecord(rec: AncientRecord): IO[Citizen] =
for {
age <- parseAge(rec.age) // successful
name <- parseName(rec.name) // error "raised"
rate <- parseRate(rec.rate) // (does not run)
} yield
Citizen(age, name, rate) // error raised in step 2
Name Happy path Sad path
Option[_] Some[_] None
Try[_] Success[_] Failure[_]
Either[E, _] Right[E, _] Left[E, _]
IO[_] IO[_] IO[_]
Functional Error Handling with Cats
MONAD TYPECLASSMONAD TYPECLASS
import cats._
import cats.effect._
import scala.util._
type EitherParsingErr[A] = Either[ParsingErr, A]
implicitly[Monad[Option]]
implicitly[Monad[Try]]
implicitly[Monad[EitherParsingErr]]
implicitly[Monad[IO]]
ERROR CHANNELSERROR CHANNELS
F[A] shape Payload Error channel
Try[A] A Throwable
IO[A] A Throwable
Either[E, A] A E
MONADERROR TYPECLASSMONADERROR TYPECLASS
import cats._
import cats.effect._
import scala.util._
type EitherParsingErr[A] = Either[ParsingErr, A]
implicitly[MonadError[Try, Throwable]]
implicitly[MonadError[IO, Throwable]]
implicitly[MonadError[EitherParsingErr, ParsingErr]]
TYPECLASS TABLETYPECLASS TABLE
Functor[_]  
Applicative[_]  
Monad[_] MonadError[_, _]
Functional Error Handling with Cats
Functional Error Handling with Cats
Functional Error Handling with Cats
PARSING WITH EITHERPARSING WITH EITHER
def parseRecord(rec: AncientRecord): Either[ParsingErr, Citizen] =
for {
age <- parseAge(rec.age) // Left[ParsingErr, Int]
name <- parseName(rec.name) // (does not run)
rate <- parseRate(rec.rate) // (does not run)
} yield
Citizen(age, name, rate) // only reports first error
GIVEN:GIVEN:
EitherEither[[EE, , AA]]
GIVEN:GIVEN:
EitherEither[[EE, , AA]]
WANT:WANT:
EitherEither[[ListList[[EE], ], AA]]
MONADS START WITH:MONADS START WITH:
EitherEither[[EE, , AA]]
MONADS START WITH:MONADS START WITH:
EitherEither[[EE, , AA]]
MONADS END WITH:MONADS END WITH:
EitherEither[[EE, , AA]]
Functional Error Handling with Cats
Functional Error Handling with Cats
ValidatedValidated[_, _][_, _]
ValidatedValidated[_, _][_, _]
def parseAge(s: String): Validated[UnreadableAge, Int]
def parseName(s: String): Validated[UnreadableName, String]
def parseRate(s: String): Validated[UnreadableRate, Double]
PARSING WITH VALIDATED???PARSING WITH VALIDATED???
def parseRecord(rec: AncientRecord): ???[Citizen] =
for {
age <- ??? // ???
name <- ??? // ???
rate <- ??? // ???
} yield
Citizen(age, name, rate) // ???
ACCUMULATIONACCUMULATION
def combine(
v1: Validated[ParsingErr, Int],
v2: Validated[ParsingErr, String]):
Validated[List[ParsingError], (Int, String)] =
(v1, v2) match {
case (Valid(n), Valid(s)) => Valid((n, s))
case (Invalid(err), Valid(s)) => Invalid(List(err))
case (Valid(n), Invalid(err)) => Invalid(List(err))
case (Invalid(e1), Invalid(e2)) => Invalid(List(e1, e2))
}
EitherEither[[EE, , AA]]
ValidatedValidated[[EE, , AA]]
VALIDATED AND EITHERVALIDATED AND EITHER
Used for capturing errors as data
"Exclusive disjunction"
(payload A or error E but never both)
Bifunctor over A and E
Name Happy path Sad path
Option[_] Some[_] None
Try[_] Success[_] Failure[_]
Either[E, _] Right[E, _] Left[E, _]
IO[_] IO[_] IO[_]
Validated[E, _] Valid[_] Invalid[E]
ERROR CHANNELSERROR CHANNELS
F[A] shape Payload Error channel
Try[A] A Throwable
IO[A] A Throwable
Either[E, A] A E
Validated[E, A] A E
APPLICATIVEERROR TYPECLASSAPPLICATIVEERROR TYPECLASS
import cats._
import cats.effect._
type EitherParsingErr[A] = Either[ParsingErr, A]
type ValidatedParsingErr[A] = Validated[ParsingErr, A]
implicitly[ApplicativeError[IO, Throwable]]
implicitly[ApplicativeError[EitherParsingErr, ParsingErr]]
implicitly[ApplicativeError[ValidatedParsingErr, ParsingErr]]
// does not compile
implicitly[MonadError[ValidatedParsingErr, ParsingErr]]
TYPECLASS TABLETYPECLASS TABLE
Functor[_]  
Applicative[_] ApplicativeError[_, _]
Monad[_] MonadError[_, _]
POSTFIX SYNTAXPOSTFIX SYNTAX
import cats.implicits._
def luckyNumber: Validated[String, Int] =
if (Random.nextBoolean)
42.valid
else
"You are unlucky.".invalid
Functional Error Handling with Cats
Functional Error Handling with Cats
ValidatedValidated[[EE, , AA]]
ValidatedValidated[[EE, , AA]]
ValidatedValidated[[EE, , AA]]
  
ValidatedValidated[[ListList[[EE], ], AA]]
EitherEither[[EE, , AA]]
EitherEither[[EE, , AA]]
EitherEither[[EE, , AA]]
  
EitherEither[[EE, , AA]]
ValidatedValidated[[ListList[[EE], ], AA]]
ValidatedValidated[[ListList[[EE], ], AA]]
ValidatedValidated[[ListList[[EE], ], AA]]
  
ValidatedValidated[[ListList[[EE], ], AA]]
ValidatedValidated[[ListList[_], _][_], _]
import cats.data._
def parseAge(s: String):
Validated[List[UnreadableAge], Int]
def parseName(s: String):
Validated[List[UnreadableName], String]
def parseRate(s: String):
Validated[List[UnreadableRate], Double]
ACCUMULATIONACCUMULATION
def combine(
v1: Validated[List[ParsingErr], Int],
v2: Validated[List[ParsingErr], String]):
Validated[List[ParsingError], (Int, String)] =
(v1, v2) match {
case (Valid(n), Valid(s)) => Valid((n, s))
case (Invalid(err), Valid(s)) => Invalid(err)
case (Valid(n), Invalid(err)) => Invalid(err)
case (Invalid(e1), Invalid(e2)) => Invalid(e1 ::: e2)
}
WITH SEMIGROUPWITH SEMIGROUP
def combine[F : Semigroup](
v1: Validated[F[ParsingErr], Int],
v2: Validated[F[ParsingErr], String]):
Validated[F[ParsingError], (Int, String)] =
(v1, v2) match {
case (Valid(n), Valid(s)) => Valid((n, s))
case (Invalid(err), Valid(s)) => Invalid(err)
case (Valid(n), Invalid(err)) => Invalid(err)
// powered by Semigroup[F]
case (Invalid(e1), Invalid(e2)) => Invalid(e1 |+| e2)
}
ValidatedValidated[[EE, , AA]]
ValidatedValidated[[FF[[EE], ], AA]]
FF :  : SemigroupSemigroup
TUPLE SYNTAXTUPLE SYNTAX
import cats._
import cats.data._
import cats.implicits._
val res: Validated[List[ParsingErr], Citizen] =
(
parseAge(rec.age),
parseName(rec.name),
parseRate(rec.rate)
)
.mapN(Citizen)
Functional Error Handling with Cats
USINGUSING .fold().fold()
val res: Validated[List[ParsingErr], Citizen] = ???
def httpErrors(errs: List[ParsingError]): HttpClientError
def httpSuccess(c: Citizen): HttpSucccess
val httpResponse: HttpResponse =
res
.fold(httpErrors, httpSuccess)
USINGUSING .leftMap().leftMap()
val res: Validated[List[ParsingErr], Citizen] = ???
def httpErrors(errs: List[ParsingError]): HttpClientError
def httpSuccess(c: Citizen): HttpSucccess
val httpResponse: HttpResponse =
res // Validated[List[ParsingErr], Citizen]
.map(httpSuccess) // Validated[List[ParsingErr], HttpSucccess]
.leftMap(httpErrors) // Validated[HttpClientError, HttpSucccess]
.merge // HttpResponse
Functional Error Handling with Cats
FIRST ERROR WINSFIRST ERROR WINS
ACCUMULATEDACCUMULATED
ERRORSERRORS
FIRST ERROR WINSFIRST ERROR WINS
FIRST ERROR WINSFIRST ERROR WINS
Modeling dependent validations
Unwrapping envelopes or decoding
FIRST ERROR WINSFIRST ERROR WINS
Modeling dependent validations
Unwrapping envelopes or decoding
Introducing gates/dependency onto independent
validations
Save on expensive computation
ACCUMULATED ERRORSACCUMULATED ERRORS
ACCUMULATED ERRORSACCUMULATED ERRORS
Modeling independent validations
Field-based structures (maps, records, objects)
ACCUMULATED ERRORSACCUMULATED ERRORS
Modeling independent validations
Field-based structures (maps, records, objects)
Minimize round-trips
ACCUMULATED ERRORSACCUMULATED ERRORS
Modeling independent validations
Field-based structures (maps, records, objects)
Minimize round-trips
Embracing parallelization
Functional Error Handling with Cats
Functional Error Handling with Cats
ListList[_][_]
import cats._
import cats.data._
import cats.implicits._
def parseAge(s: String):
Validated[List[UnreadableAge], Int]
def parseName(s: String):
Validated[List[UnreadableName], String]
def parseRate(s: String):
Validated[List[UnreadableRate], Double]
implicitly[Semigroup[List]]
NonEmptyListNonEmptyList[_][_]
import cats._
import cats.data._
import cats.implicits._
def parseAge(s: String):
Validated[NonEmptyList[UnreadableAge], Int]
def parseName(s: String):
Validated[NonEmptyList[UnreadableName], String]
def parseRate(s: String):
Validated[NonEmptyList[UnreadableRate], Double]
implicitly[Semigroup[NonEmptyList]]
POSTFIX SYNTAXPOSTFIX SYNTAX
import cats.data._
import cats.implicits._
def luckyNumber: Validated[NonEmptyList[String], Int] =
if (Random.nextBoolean)
42.validNel
else
"You are unlucky.".invalidNel
Functional Error Handling with Cats
APPENDINGAPPENDING
List(1, 2, 3) ++ List(4)
APPENDING FREQUENTLYAPPENDING FREQUENTLY
List(1, 2, 3) ++ List(4)
List(1, 2, 3, 4) ++ List(5)
List(1, 2, 3, 4, 5) ++ List(8, 9)
List(1, 2) ++ List(3, 4) ++ List(8, 9)
Functional Error Handling with Cats
LIST ACCUMULATIONLIST ACCUMULATION
// read from left to right
List(1, 2, 3, 4, 5) ++ List(8, 9)
LIST ACCUMULATION (A)LIST ACCUMULATION (A)
// via repeated traversals
List(1, 2, 3, 4, 5) ++ List(8, 9)
List(1, 2, 3, 4) ++ List(5, 8, 9)
List(1, 2, 3) ++ List(4, 5, 8, 9)
List(1, 2) ++ List(3, 4, 5, 8, 9)
List(1) ++ List(2, 3, 4, 5, 8, 9)
List(1, 2, 3, 4, 5, 8, 9)
LIST ACCUMULATION (B)LIST ACCUMULATION (B)
// via reverse list, built using fast prepend
List(1, 2, 3, 4) ++ ReverseList()
List(2, 3, 4) ++ ReverseList(1)
List(3, 4) ++ ReverseList(2, 1)
List(4) ++ ReverseList(3, 2, 1)
List() ++ ReverseList(4, 3, 2, 1)
SEQUENCESSEQUENCES
List(1, 2, 3, 4)
Seq(5)
Vector(6, 7, 8)
Nested(
List(9),
Array(10, 11, 12))
CHAINCHAINED TOGETHERED TOGETHER
Chain(
List(1, 2, 3, 4),
Seq(5),
Vector(6, 7, 8),
Chain(
List(9),
Array(10, 11, 12)))
ChainChain[_][_]
def parseAge(s: String):
Validated[Chain[UnreadableAge], Int]
def parseName(s: String):
Validated[Chain[UnreadableName], String]
def parseRate(s: String):
Validated[Chain[UnreadableRate], Double]
implicitly[Semigroup[Chain]]
NonEmptyChainNonEmptyChain[_][_]
def parseAge(s: String):
Validated[NonEmptyChain[UnreadableAge], Int]
def parseName(s: String):
Validated[NonEmptyChain[UnreadableName], String]
def parseRate(s: String):
Validated[NonEmptyChain[UnreadableRate], Double]
implicitly[Semigroup[NonEmptyChain]]
SEMIGROUPSEMIGROUP COLLECTIONSCOLLECTIONS
Name Provider Empty? Accumulation
performance
List Scala ✅ O(n^2)
NonEmptyList ❌ O(n^2)
Chain ✅ constant
NonEmptyChain ❌ constant
POSTFIX SYNTAXPOSTFIX SYNTAX
import cats.implicits._
def luckyNumber: Validated[NonEmptyChain[String], Int] =
if (Random.nextBoolean)
42.validNec
else
"You are unlucky.".invalidNec
Functional Error Handling with Cats
ALGEBRASALGEBRAS
trait ParserAlg[F[_]] {
def parseAge(s: String): F[Int]
def parseName(s: String): F[String]
def parseRate(s: String): F[Double]
}
TYPECLASS METHODSTYPECLASS METHODS
class BadParser[F[_]](implicit F: ApplicativeError[F, Throwable]) {
def parseAge(s: String): F[Int] =
// raised, not thrown
F.raiseError(new Exception("what a world"))
}
NESTEDNESTED FF ANDAND GG
trait FancyParserAlg[F[_], G[_]] {
def parseAge(s: String): F[G[Int]]
def parseName(s: String): F[G[String]]
def parseRate(s: String): F[G[Double]]
}
FF WITH TRANSFORMERWITH TRANSFORMER GTGT
trait FancyParserAlg[F[_]] {
def parseAge(s: String): GT[F, Int]
def parseName(s: String): GT[F, String]
def parseRate(s: String): GT[F, Double]
}
FURTHER READINGFURTHER READING
Contains Chain and Validated, from the Cats
microsite
Cats Data Types
JOBS.DISNEYCAREERS.COMJOBS.DISNEYCAREERS.COM
@@mark canlas nycmark canlas nyc
Ad

More Related Content

What's hot (20)

Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type Classes
John De Goes
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and Cats
Philip Schwarz
 
Monad Laws Must be Checked
Monad Laws Must be CheckedMonad Laws Must be Checked
Monad Laws Must be Checked
Philip Schwarz
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...
Philip Schwarz
 
Introduction to numpy Session 1
Introduction to numpy Session 1Introduction to numpy Session 1
Introduction to numpy Session 1
Jatin Miglani
 
Left and Right Folds - Comparison of a mathematical definition and a programm...
Left and Right Folds- Comparison of a mathematical definition and a programm...Left and Right Folds- Comparison of a mathematical definition and a programm...
Left and Right Folds - Comparison of a mathematical definition and a programm...
Philip Schwarz
 
Functional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 WayFunctional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 Way
Debasish Ghosh
 
Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web Stack
GaryCoady
 
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
Philip Schwarz
 
Introduction to programming with ZIO functional effects
Introduction to programming with ZIO functional effectsIntroduction to programming with ZIO functional effects
Introduction to programming with ZIO functional effects
Jorge Vásquez
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1
Philip Schwarz
 
Sql Antipatterns Strike Back
Sql Antipatterns Strike BackSql Antipatterns Strike Back
Sql Antipatterns Strike Back
Karwin Software Solutions LLC
 
Quill vs Slick Smackdown
Quill vs Slick SmackdownQuill vs Slick Smackdown
Quill vs Slick Smackdown
Alexander Ioffe
 
ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022
Alexander Ioffe
 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Philip Schwarz
 
Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)
Scott Wlaschin
 
Базы данных в 2020
Базы данных в 2020Базы данных в 2020
Базы данных в 2020
Timur Shemsedinov
 
Effective testing with pytest
Effective testing with pytestEffective testing with pytest
Effective testing with pytest
Hector Canto
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Chris Richardson
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and Effects
Martin Odersky
 
Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type Classes
John De Goes
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and Cats
Philip Schwarz
 
Monad Laws Must be Checked
Monad Laws Must be CheckedMonad Laws Must be Checked
Monad Laws Must be Checked
Philip Schwarz
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...
Philip Schwarz
 
Introduction to numpy Session 1
Introduction to numpy Session 1Introduction to numpy Session 1
Introduction to numpy Session 1
Jatin Miglani
 
Left and Right Folds - Comparison of a mathematical definition and a programm...
Left and Right Folds- Comparison of a mathematical definition and a programm...Left and Right Folds- Comparison of a mathematical definition and a programm...
Left and Right Folds - Comparison of a mathematical definition and a programm...
Philip Schwarz
 
Functional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 WayFunctional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 Way
Debasish Ghosh
 
Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web Stack
GaryCoady
 
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
N-Queens Combinatorial Problem - Polyglot FP for Fun and Profit – Haskell and...
Philip Schwarz
 
Introduction to programming with ZIO functional effects
Introduction to programming with ZIO functional effectsIntroduction to programming with ZIO functional effects
Introduction to programming with ZIO functional effects
Jorge Vásquez
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1
Philip Schwarz
 
Quill vs Slick Smackdown
Quill vs Slick SmackdownQuill vs Slick Smackdown
Quill vs Slick Smackdown
Alexander Ioffe
 
ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022
Alexander Ioffe
 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Philip Schwarz
 
Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)
Scott Wlaschin
 
Базы данных в 2020
Базы данных в 2020Базы данных в 2020
Базы данных в 2020
Timur Shemsedinov
 
Effective testing with pytest
Effective testing with pytestEffective testing with pytest
Effective testing with pytest
Hector Canto
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Chris Richardson
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and Effects
Martin Odersky
 

Similar to Functional Error Handling with Cats (20)

Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
Jonas Bonér
 
Pragmatic Real-World Scala
Pragmatic Real-World ScalaPragmatic Real-World Scala
Pragmatic Real-World Scala
parag978978
 
Beginning Scala Svcc 2009
Beginning Scala Svcc 2009Beginning Scala Svcc 2009
Beginning Scala Svcc 2009
David Pollak
 
Achieving Parsing Sanity In Erlang
Achieving Parsing Sanity In ErlangAchieving Parsing Sanity In Erlang
Achieving Parsing Sanity In Erlang
Sean Cribbs
 
More expressive types for spark with frameless
More expressive types for spark with framelessMore expressive types for spark with frameless
More expressive types for spark with frameless
Miguel Pérez Pasalodos
 
C# Cheat Sheet
C# Cheat SheetC# Cheat Sheet
C# Cheat Sheet
GlowTouch
 
Introduction to R
Introduction to RIntroduction to R
Introduction to R
Sander Kieft
 
Graph Database Query Languages
Graph Database Query LanguagesGraph Database Query Languages
Graph Database Query Languages
Jay Coskey
 
Useful javascript
Useful javascriptUseful javascript
Useful javascript
Lei Kang
 
Plc (1)
Plc (1)Plc (1)
Plc (1)
James Croft
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing Functionally
Sean Cribbs
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
decoupled
 
A tour of Python
A tour of PythonA tour of Python
A tour of Python
Aleksandar Veselinovic
 
Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!
Paige Bailey
 
An introduction to property-based testing
An introduction to property-based testingAn introduction to property-based testing
An introduction to property-based testing
Vincent Pradeilles
 
ScalaBlitz
ScalaBlitzScalaBlitz
ScalaBlitz
Aleksandar Prokopec
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
Jonas Bonér
 
Pragmatic Real-World Scala
Pragmatic Real-World ScalaPragmatic Real-World Scala
Pragmatic Real-World Scala
parag978978
 
Beginning Scala Svcc 2009
Beginning Scala Svcc 2009Beginning Scala Svcc 2009
Beginning Scala Svcc 2009
David Pollak
 
Achieving Parsing Sanity In Erlang
Achieving Parsing Sanity In ErlangAchieving Parsing Sanity In Erlang
Achieving Parsing Sanity In Erlang
Sean Cribbs
 
More expressive types for spark with frameless
More expressive types for spark with framelessMore expressive types for spark with frameless
More expressive types for spark with frameless
Miguel Pérez Pasalodos
 
C# Cheat Sheet
C# Cheat SheetC# Cheat Sheet
C# Cheat Sheet
GlowTouch
 
Graph Database Query Languages
Graph Database Query LanguagesGraph Database Query Languages
Graph Database Query Languages
Jay Coskey
 
Useful javascript
Useful javascriptUseful javascript
Useful javascript
Lei Kang
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing Functionally
Sean Cribbs
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
decoupled
 
Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!Python 101++: Let's Get Down to Business!
Python 101++: Let's Get Down to Business!
Paige Bailey
 
An introduction to property-based testing
An introduction to property-based testingAn introduction to property-based testing
An introduction to property-based testing
Vincent Pradeilles
 
Ad

Recently uploaded (20)

F-Secure Freedome VPN 2025 Crack Plus Activation New Version
F-Secure Freedome VPN 2025 Crack Plus Activation  New VersionF-Secure Freedome VPN 2025 Crack Plus Activation  New Version
F-Secure Freedome VPN 2025 Crack Plus Activation New Version
saimabibi60507
 
WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)
sh607827
 
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Ranjan Baisak
 
Explaining GitHub Actions Failures with Large Language Models Challenges, In...
Explaining GitHub Actions Failures with Large Language Models Challenges, In...Explaining GitHub Actions Failures with Large Language Models Challenges, In...
Explaining GitHub Actions Failures with Large Language Models Challenges, In...
ssuserb14185
 
Download Wondershare Filmora Crack [2025] With Latest
Download Wondershare Filmora Crack [2025] With LatestDownload Wondershare Filmora Crack [2025] With Latest
Download Wondershare Filmora Crack [2025] With Latest
tahirabibi60507
 
Solidworks Crack 2025 latest new + license code
Solidworks Crack 2025 latest new + license codeSolidworks Crack 2025 latest new + license code
Solidworks Crack 2025 latest new + license code
aneelaramzan63
 
Automation Techniques in RPA - UiPath Certificate
Automation Techniques in RPA - UiPath CertificateAutomation Techniques in RPA - UiPath Certificate
Automation Techniques in RPA - UiPath Certificate
VICTOR MAESTRE RAMIREZ
 
Designing AI-Powered APIs on Azure: Best Practices& Considerations
Designing AI-Powered APIs on Azure: Best Practices& ConsiderationsDesigning AI-Powered APIs on Azure: Best Practices& Considerations
Designing AI-Powered APIs on Azure: Best Practices& Considerations
Dinusha Kumarasiri
 
EASEUS Partition Master Crack + License Code
EASEUS Partition Master Crack + License CodeEASEUS Partition Master Crack + License Code
EASEUS Partition Master Crack + License Code
aneelaramzan63
 
Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025
kashifyounis067
 
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
AxisTechnolabs
 
Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025
kashifyounis067
 
Not So Common Memory Leaks in Java Webinar
Not So Common Memory Leaks in Java WebinarNot So Common Memory Leaks in Java Webinar
Not So Common Memory Leaks in Java Webinar
Tier1 app
 
Societal challenges of AI: biases, multilinguism and sustainability
Societal challenges of AI: biases, multilinguism and sustainabilitySocietal challenges of AI: biases, multilinguism and sustainability
Societal challenges of AI: biases, multilinguism and sustainability
Jordi Cabot
 
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
steaveroggers
 
Kubernetes_101_Zero_to_Platform_Engineer.pptx
Kubernetes_101_Zero_to_Platform_Engineer.pptxKubernetes_101_Zero_to_Platform_Engineer.pptx
Kubernetes_101_Zero_to_Platform_Engineer.pptx
CloudScouts
 
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software DevelopmentSecure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Shubham Joshi
 
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AIScaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
danshalev
 
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Lionel Briand
 
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Dele Amefo
 
F-Secure Freedome VPN 2025 Crack Plus Activation New Version
F-Secure Freedome VPN 2025 Crack Plus Activation  New VersionF-Secure Freedome VPN 2025 Crack Plus Activation  New Version
F-Secure Freedome VPN 2025 Crack Plus Activation New Version
saimabibi60507
 
WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)
sh607827
 
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Ranjan Baisak
 
Explaining GitHub Actions Failures with Large Language Models Challenges, In...
Explaining GitHub Actions Failures with Large Language Models Challenges, In...Explaining GitHub Actions Failures with Large Language Models Challenges, In...
Explaining GitHub Actions Failures with Large Language Models Challenges, In...
ssuserb14185
 
Download Wondershare Filmora Crack [2025] With Latest
Download Wondershare Filmora Crack [2025] With LatestDownload Wondershare Filmora Crack [2025] With Latest
Download Wondershare Filmora Crack [2025] With Latest
tahirabibi60507
 
Solidworks Crack 2025 latest new + license code
Solidworks Crack 2025 latest new + license codeSolidworks Crack 2025 latest new + license code
Solidworks Crack 2025 latest new + license code
aneelaramzan63
 
Automation Techniques in RPA - UiPath Certificate
Automation Techniques in RPA - UiPath CertificateAutomation Techniques in RPA - UiPath Certificate
Automation Techniques in RPA - UiPath Certificate
VICTOR MAESTRE RAMIREZ
 
Designing AI-Powered APIs on Azure: Best Practices& Considerations
Designing AI-Powered APIs on Azure: Best Practices& ConsiderationsDesigning AI-Powered APIs on Azure: Best Practices& Considerations
Designing AI-Powered APIs on Azure: Best Practices& Considerations
Dinusha Kumarasiri
 
EASEUS Partition Master Crack + License Code
EASEUS Partition Master Crack + License CodeEASEUS Partition Master Crack + License Code
EASEUS Partition Master Crack + License Code
aneelaramzan63
 
Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025
kashifyounis067
 
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
AxisTechnolabs
 
Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025
kashifyounis067
 
Not So Common Memory Leaks in Java Webinar
Not So Common Memory Leaks in Java WebinarNot So Common Memory Leaks in Java Webinar
Not So Common Memory Leaks in Java Webinar
Tier1 app
 
Societal challenges of AI: biases, multilinguism and sustainability
Societal challenges of AI: biases, multilinguism and sustainabilitySocietal challenges of AI: biases, multilinguism and sustainability
Societal challenges of AI: biases, multilinguism and sustainability
Jordi Cabot
 
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
steaveroggers
 
Kubernetes_101_Zero_to_Platform_Engineer.pptx
Kubernetes_101_Zero_to_Platform_Engineer.pptxKubernetes_101_Zero_to_Platform_Engineer.pptx
Kubernetes_101_Zero_to_Platform_Engineer.pptx
CloudScouts
 
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software DevelopmentSecure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Shubham Joshi
 
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AIScaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
danshalev
 
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Lionel Briand
 
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Dele Amefo
 
Ad

Functional Error Handling with Cats