SlideShare a Scribd company logo
1 of 124
Download to read offline
FUNCTIONALFUNCTIONAL
ERROR HANDLINGERROR HANDLING
WITH CATSWITH CATS
MARK CANLASMARK CANLAS ·· NE SCALA 2020NE SCALA 2020
OPTIONOPTION[_][_]
TRYTRY[_][_]
EITHEREITHER[_, _][_, _]
FUNCTORFUNCTOR[_][_]
APPLICATIVEAPPLICATIVE[_][_]
MONADMONAD[_][_]
ERRORS ASERRORS AS DATADATA
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
PARSING FUNCTIONSPARSING FUNCTIONS
def parseAge(s: String)
def parseName(s: String)
def parseRate(s: String)
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
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]
Name Happy path Sad path
Option[_] Some[_] None
Try[_] Success[_] Failure[_]
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
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]
Name Happy path Sad path
Option[_] Some[_] None
Try[_] Success[_] Failure[_]
Either[E, _] Right[E, _] Left[E, _]
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
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[_]
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[_, _]
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]]
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
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)
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
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
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
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)
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
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

More Related Content

What's hot

ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022Alexander Ioffe
 
ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaWiem Zine Elabidine
 
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 StackGaryCoady
 
A Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOA Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOJorge Vásquez
 
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшe
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшeQA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшe
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшeQAFest
 
Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type ClassesJohn De Goes
 
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldFunctional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldJorge Vásquez
 
Boost your productivity with Scala tooling!
Boost your productivity  with Scala tooling!Boost your productivity  with Scala tooling!
Boost your productivity with Scala tooling!MeriamLachkar1
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadOliver Daff
 
Running Free with the Monads
Running Free with the MonadsRunning Free with the Monads
Running Free with the Monadskenbot
 
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
 
Array in c language
Array in c languageArray in c language
Array in c languagehome
 
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
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Mario Fusco
 
Be Smart, Constrain Your Types to Free Your Brain!
Be Smart, Constrain Your Types to Free Your Brain!Be Smart, Constrain Your Types to Free Your Brain!
Be Smart, Constrain Your Types to Free Your Brain!Jorge Vásquez
 
Relational algebra
Relational algebraRelational algebra
Relational algebrashynajain
 

What's hot (20)

Php string function
Php string function Php string function
Php string function
 
ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022
 
ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in Scala
 
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
 
A Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOA Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIO
 
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшe
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшeQA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшe
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшe
 
Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type Classes
 
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldFunctional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorld
 
JDBC
JDBCJDBC
JDBC
 
Boost your productivity with Scala tooling!
Boost your productivity  with Scala tooling!Boost your productivity  with Scala tooling!
Boost your productivity with Scala tooling!
 
Functor, Apply, Applicative And Monad
Functor, Apply, Applicative And MonadFunctor, Apply, Applicative And Monad
Functor, Apply, Applicative And Monad
 
Running Free with the Monads
Running Free with the MonadsRunning Free with the Monads
Running Free with the Monads
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them All
 
Zio in real world
Zio in real worldZio in real world
Zio in real world
 
Array in c language
Array in c languageArray in c language
Array in c language
 
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...
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 
Be Smart, Constrain Your Types to Free Your Brain!
Be Smart, Constrain Your Types to Free Your Brain!Be Smart, Constrain Your Types to Free Your Brain!
Be Smart, Constrain Your Types to Free Your Brain!
 
Relational algebra
Relational algebraRelational algebra
Relational algebra
 
PlantUML introduction
PlantUML introductionPlantUML introduction
PlantUML introduction
 

Similar to Functional Error Handling with Cats

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 Scalaparag978978
 
Beginning Scala Svcc 2009
Beginning Scala Svcc 2009Beginning Scala Svcc 2009
Beginning Scala Svcc 2009David Pollak
 
Achieving Parsing Sanity In Erlang
Achieving Parsing Sanity In ErlangAchieving Parsing Sanity In Erlang
Achieving Parsing Sanity In ErlangSean 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 framelessMiguel Pérez Pasalodos
 
C# Cheat Sheet
C# Cheat SheetC# Cheat Sheet
C# Cheat SheetGlowTouch
 
Graph Database Query Languages
Graph Database Query LanguagesGraph Database Query Languages
Graph Database Query LanguagesJay Coskey
 
Useful javascript
Useful javascriptUseful javascript
Useful javascriptLei Kang
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallySean Cribbs
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7decoupled
 
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 testingVincent Pradeilles
 

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)
 
Pragmatic Real-World Scala
Pragmatic Real-World ScalaPragmatic Real-World Scala
Pragmatic Real-World Scala
 
Beginning Scala Svcc 2009
Beginning Scala Svcc 2009Beginning Scala Svcc 2009
Beginning Scala Svcc 2009
 
Achieving Parsing Sanity In Erlang
Achieving Parsing Sanity In ErlangAchieving Parsing Sanity In Erlang
Achieving Parsing Sanity In Erlang
 
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
 
C# Cheat Sheet
C# Cheat SheetC# Cheat Sheet
C# Cheat Sheet
 
Introduction to R
Introduction to RIntroduction to R
Introduction to R
 
Graph Database Query Languages
Graph Database Query LanguagesGraph Database Query Languages
Graph Database Query Languages
 
Useful javascript
Useful javascriptUseful javascript
Useful javascript
 
Plc (1)
Plc (1)Plc (1)
Plc (1)
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
Round PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing FunctionallyRound PEG, Round Hole - Parsing Functionally
Round PEG, Round Hole - Parsing Functionally
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
 
A tour of Python
A tour of PythonA tour of Python
A tour of Python
 
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!
 
An introduction to property-based testing
An introduction to property-based testingAn introduction to property-based testing
An introduction to property-based testing
 
ScalaBlitz
ScalaBlitzScalaBlitz
ScalaBlitz
 

Recently uploaded

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
 
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
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
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
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
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
 
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
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
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
 
办理学位证(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
 

Recently uploaded (20)

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
 
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
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
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...
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
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
 
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
 
Odoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting ServiceOdoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting Service
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
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
 
办理学位证(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
 

Functional Error Handling with Cats