Ilustramos las diferentes formas de manejar errores con Scala y Typelevel cats. Comparamos excepciones en programación imperativa con el manejo funcional de tipos como Try, Either, Validated e Ior.
Este documento resume los vectores en PHP, incluyendo cómo se declaran, estructuran y acceden a sus elementos. Explica los diferentes tipos de índices, funciones para recorrer, ordenar, manipular y extraer información de vectores. También cubre vectores anidados, asociativos y multidimensionales, dando ejemplos de su uso.
Wonder Woman has several superpowers including flight, indestructible bracelets, a magic tiara that can be used as a boomerang, a lasso of truth, and utility earrings. She also has super strength. She is Princess Diana of Themyscira who was created from clay. If a man manages to tie her bracelets together, she will lose her powers.
The document discusses the Big Brothers Big Sisters of America's "Bigs in Blue" program. The program pairs police officers with elementary and middle school youth to build trusting relationships between law enforcement and communities. It launched in January 2017 with officers mentoring children for 30 minutes per week at schools. Big Brothers Big Sisters has raised over $1 million of its $5 million fundraising goal to support the program's development.
El documento describe un concurso de fotografía organizado por el diario Ideal con motivo de la celebración del Milenio del Reino de Granada. El concurso se llama "las huellas del Milenio" y muestra las fotografías seleccionadas de los concursantes para elegir las diez mejores en cada categoría y la ganadora general.
El juicio de amparo tiene su origen en la Constitución Mexicana de 1857 para proteger a los ciudadanos contra violaciones a sus derechos por parte de autoridades. Se creó para defender a los individuos de posibles abusos de poder de otras ramas del gobierno y asegurar el respeto a las garantías individuales establecidas en la constitución.
Este documento descreve o 1o Fórum de TI e Inovação para Tribunais de Contas, que ocorrerá em Brasília nos dias 5 e 6 de abril de 2017. O evento trará discussões sobre novas tecnologias como inteligência artificial, big data e cloud computing e como os tribunais podem aplicá-las. Também abordará temas como governança de TI, compras e processos licitatórios nos tribunais. Contará com painéis e apresentações de cases sobre esses assuntos.
Este documento resume los vectores en PHP, incluyendo cómo se declaran, estructuran y acceden a sus elementos. Explica los diferentes tipos de índices, funciones para recorrer, ordenar, manipular y extraer información de vectores. También cubre vectores anidados, asociativos y multidimensionales, dando ejemplos de su uso.
Wonder Woman has several superpowers including flight, indestructible bracelets, a magic tiara that can be used as a boomerang, a lasso of truth, and utility earrings. She also has super strength. She is Princess Diana of Themyscira who was created from clay. If a man manages to tie her bracelets together, she will lose her powers.
The document discusses the Big Brothers Big Sisters of America's "Bigs in Blue" program. The program pairs police officers with elementary and middle school youth to build trusting relationships between law enforcement and communities. It launched in January 2017 with officers mentoring children for 30 minutes per week at schools. Big Brothers Big Sisters has raised over $1 million of its $5 million fundraising goal to support the program's development.
El documento describe un concurso de fotografía organizado por el diario Ideal con motivo de la celebración del Milenio del Reino de Granada. El concurso se llama "las huellas del Milenio" y muestra las fotografías seleccionadas de los concursantes para elegir las diez mejores en cada categoría y la ganadora general.
El juicio de amparo tiene su origen en la Constitución Mexicana de 1857 para proteger a los ciudadanos contra violaciones a sus derechos por parte de autoridades. Se creó para defender a los individuos de posibles abusos de poder de otras ramas del gobierno y asegurar el respeto a las garantías individuales establecidas en la constitución.
Este documento descreve o 1o Fórum de TI e Inovação para Tribunais de Contas, que ocorrerá em Brasília nos dias 5 e 6 de abril de 2017. O evento trará discussões sobre novas tecnologias como inteligência artificial, big data e cloud computing e como os tribunais podem aplicá-las. Também abordará temas como governança de TI, compras e processos licitatórios nos tribunais. Contará com painéis e apresentações de cases sobre esses assuntos.
The document discusses total rewards for volunteering. It focuses on non-monetary rewards received from volunteering such as feeling appreciated, gaining new skills, improving health and well-being, expanding social networks, and increasing career opportunities. Volunteering provides both intrinsic and extrinsic rewards beyond just financial compensation.
Santa Fe Avenue Streetscape-Survey #2 ResultsCity of Salina
The document appears to be the results of a survey about proposed concepts for renovating the downtown streetscape of Salina, Kansas. The survey included questions about two concepts for the streetscape, preference for various design features, use of a center lane on Santa Fe Avenue, potential removal of some traffic signals, and level of agreement with statements regarding making the downtown more inviting and complementing the art deco atmosphere. The majority of respondents agreed that the illustrations would make downtown more inviting and engaging and complement the art deco style, and supported allowing both delivery and passenger parking in the center lane for one hour.
The author visited the Museum of London and saw an exhibition about a royal prince from Ghana. They found the exhibition educational as it helped them understand how slaves were manipulated and treated. The pictures provided insight into black-British history that will be useful for the author's final school project.
The document provides information on various government job openings, including:
- Hindustan Aeronautics Limited is hiring 173 Operators with a monthly pay scale of Rs. 26,342.
- The Madhya Pradesh Public Service Commission has openings for 25 Sport/Youth Welfare Officers with a pay scale of Rs. 9,300-34,800 and grade pay of Rs. 4,200.
- National Seeds Corporation has openings for Trainees, Senior Trainees, and Diploma Trainees, with pay scales ranging from Rs. 7,000-20,300 to Rs. 9,400-25,700.
The document summarizes the student's process in developing a fighting game. It discusses research done on existing fighting games to determine key elements to include. Planning involved mind maps but final product differed significantly from plans due to time constraints. Time management was an issue as too much time was spent on characters over gameplay. Technical qualities were similar to research games but lacked detail and naming. Aesthetic qualities and audience appeal were not fully developed. Peer feedback noted strengths but improvements could have been made regarding details, animation, and backdrops.
James has decided to invest and probably live in Portugal.
He already knows the country quite good, as well as it's taxations rules and advantages. But now James have another doubt!
He already has a company in his own country and he is divided between to possibilities:
To register a branch office; or
Create a Portuguese Company.
James already learned about the branch office process, so in this video we'll see how he can set a company in Portugal.
- Learn more at http://www.uwu.pt
This document provides an overview of AlgoAnalytics, an analytics consultancy company that uses advanced machine learning techniques. The summary is as follows:
(1) AlgoAnalytics provides predictive analytics solutions for retail, healthcare, financial services, and other industries using techniques like deep learning, natural language processing, and computer vision on structured, text, image and sound data.
(2) The CEO and founder, Aniruddha Pant, has over 20 years of experience applying mathematical techniques to business problems. Some of AlgoAnalytics' work includes recommender systems, demand prediction, image analysis, and customer churn prevention for online retail.
(3) Examples of AlgoAnalytics' predictive models shown include an
Este documento presenta los conceptos básicos del lenguaje PHP, incluyendo la sintaxis, tipos de datos, variables, constantes, expresiones, estructuras de control, funciones, tablas y bibliotecas de funciones. Explica cómo incrustar código PHP en HTML, imprimir mensajes y usar comentarios.
Este documento introduce los conceptos básicos del lenguaje PHP, incluyendo su sintaxis, tipos de datos, variables, constantes, expresiones, estructuras de control, funciones, tablas y bibliotecas de funciones. Explica cada uno de estos conceptos a través de ejemplos y comparaciones con C, con el objetivo de proporcionar una introducción general al lenguaje PHP.
El documento describe las características principales del lenguaje de programación Ruby. Ruby es un lenguaje interpretado, orientado a objetos y de tipado dinámico. No requiere declaraciones de variables y tiene una sintaxis simple. Todo en Ruby es un objeto y admite características como clases, herencia, métodos, bloques e iteradores.
El documento describe las características principales del lenguaje de programación Ruby. Ruby es un lenguaje interpretado, orientado a objetos y de tipado dinámico. No requiere declaraciones de variables y tiene una sintaxis simple. Todo en Ruby es un objeto y admite características como clases, herencia, métodos, iteradores, bloques, expresiones regulares y manejo de excepciones.
Este documento presenta el tema 2 de un curso de PHP. Explica conceptos básicos del lenguaje como sintaxis, tipos de datos, variables, constantes, expresiones, estructuras de control, funciones y tablas. También introduce bibliotecas de funciones comunes.
Expresiones regulares son patrones que se usan para buscar coincidencias en cadenas de texto. Se componen de un patrón o patrones a buscar y modificadores como cuantificadores que definen la frecuencia de aparición. Existen tres formas de declarar expresiones regulares en JavaScript y el objeto RegExp proporciona métodos como exec(), test(), match() para realizar búsquedas.
El documento compara los lenguajes C# y JavaScript, destacando que C# es de tipado fuerte y estático mientras que JavaScript es de tipado débil y dinámico. Explica conceptos clave de JavaScript como duck typing, tipos de datos, ámbito global, hoisting de variables, el uso de this, valores truthy y falsy, operadores de igualdad, funciones, patrones de módulos y marcos comunes. También menciona herramientas útiles para JavaScript.
The document discusses total rewards for volunteering. It focuses on non-monetary rewards received from volunteering such as feeling appreciated, gaining new skills, improving health and well-being, expanding social networks, and increasing career opportunities. Volunteering provides both intrinsic and extrinsic rewards beyond just financial compensation.
Santa Fe Avenue Streetscape-Survey #2 ResultsCity of Salina
The document appears to be the results of a survey about proposed concepts for renovating the downtown streetscape of Salina, Kansas. The survey included questions about two concepts for the streetscape, preference for various design features, use of a center lane on Santa Fe Avenue, potential removal of some traffic signals, and level of agreement with statements regarding making the downtown more inviting and complementing the art deco atmosphere. The majority of respondents agreed that the illustrations would make downtown more inviting and engaging and complement the art deco style, and supported allowing both delivery and passenger parking in the center lane for one hour.
The author visited the Museum of London and saw an exhibition about a royal prince from Ghana. They found the exhibition educational as it helped them understand how slaves were manipulated and treated. The pictures provided insight into black-British history that will be useful for the author's final school project.
The document provides information on various government job openings, including:
- Hindustan Aeronautics Limited is hiring 173 Operators with a monthly pay scale of Rs. 26,342.
- The Madhya Pradesh Public Service Commission has openings for 25 Sport/Youth Welfare Officers with a pay scale of Rs. 9,300-34,800 and grade pay of Rs. 4,200.
- National Seeds Corporation has openings for Trainees, Senior Trainees, and Diploma Trainees, with pay scales ranging from Rs. 7,000-20,300 to Rs. 9,400-25,700.
The document summarizes the student's process in developing a fighting game. It discusses research done on existing fighting games to determine key elements to include. Planning involved mind maps but final product differed significantly from plans due to time constraints. Time management was an issue as too much time was spent on characters over gameplay. Technical qualities were similar to research games but lacked detail and naming. Aesthetic qualities and audience appeal were not fully developed. Peer feedback noted strengths but improvements could have been made regarding details, animation, and backdrops.
James has decided to invest and probably live in Portugal.
He already knows the country quite good, as well as it's taxations rules and advantages. But now James have another doubt!
He already has a company in his own country and he is divided between to possibilities:
To register a branch office; or
Create a Portuguese Company.
James already learned about the branch office process, so in this video we'll see how he can set a company in Portugal.
- Learn more at http://www.uwu.pt
This document provides an overview of AlgoAnalytics, an analytics consultancy company that uses advanced machine learning techniques. The summary is as follows:
(1) AlgoAnalytics provides predictive analytics solutions for retail, healthcare, financial services, and other industries using techniques like deep learning, natural language processing, and computer vision on structured, text, image and sound data.
(2) The CEO and founder, Aniruddha Pant, has over 20 years of experience applying mathematical techniques to business problems. Some of AlgoAnalytics' work includes recommender systems, demand prediction, image analysis, and customer churn prevention for online retail.
(3) Examples of AlgoAnalytics' predictive models shown include an
Este documento presenta los conceptos básicos del lenguaje PHP, incluyendo la sintaxis, tipos de datos, variables, constantes, expresiones, estructuras de control, funciones, tablas y bibliotecas de funciones. Explica cómo incrustar código PHP en HTML, imprimir mensajes y usar comentarios.
Este documento introduce los conceptos básicos del lenguaje PHP, incluyendo su sintaxis, tipos de datos, variables, constantes, expresiones, estructuras de control, funciones, tablas y bibliotecas de funciones. Explica cada uno de estos conceptos a través de ejemplos y comparaciones con C, con el objetivo de proporcionar una introducción general al lenguaje PHP.
El documento describe las características principales del lenguaje de programación Ruby. Ruby es un lenguaje interpretado, orientado a objetos y de tipado dinámico. No requiere declaraciones de variables y tiene una sintaxis simple. Todo en Ruby es un objeto y admite características como clases, herencia, métodos, bloques e iteradores.
El documento describe las características principales del lenguaje de programación Ruby. Ruby es un lenguaje interpretado, orientado a objetos y de tipado dinámico. No requiere declaraciones de variables y tiene una sintaxis simple. Todo en Ruby es un objeto y admite características como clases, herencia, métodos, iteradores, bloques, expresiones regulares y manejo de excepciones.
Este documento presenta el tema 2 de un curso de PHP. Explica conceptos básicos del lenguaje como sintaxis, tipos de datos, variables, constantes, expresiones, estructuras de control, funciones y tablas. También introduce bibliotecas de funciones comunes.
Expresiones regulares son patrones que se usan para buscar coincidencias en cadenas de texto. Se componen de un patrón o patrones a buscar y modificadores como cuantificadores que definen la frecuencia de aparición. Existen tres formas de declarar expresiones regulares en JavaScript y el objeto RegExp proporciona métodos como exec(), test(), match() para realizar búsquedas.
El documento compara los lenguajes C# y JavaScript, destacando que C# es de tipado fuerte y estático mientras que JavaScript es de tipado débil y dinámico. Explica conceptos clave de JavaScript como duck typing, tipos de datos, ámbito global, hoisting de variables, el uso de this, valores truthy y falsy, operadores de igualdad, funciones, patrones de módulos y marcos comunes. También menciona herramientas útiles para JavaScript.
La inteligencia artificial sigue evolucionando rápidamente, prometiendo transformar múltiples aspectos de la sociedad mientras plantea importantes cuestiones que requieren una cuidadosa consideración y regulación.
Uso de las Tics en la vida cotidiana.pptx231485414
Las Tecnologías de la Información y las Comunicaciones (TIC), son el conjunto de recursos, herramientas, equipos, programas informáticos, aplicaciones, redes y medios.
Infografia TCP/IP (Transmission Control Protocol/Internet Protocol)codesiret
Los protocolos son conjuntos de
normas para formatos de mensaje y
procedimientos que permiten a las
máquinas y los programas de aplicación
intercambiar información.
El uso de las TIC en la vida cotidiana.pptxjgvanessa23
En esta presentación, he compartido información sobre las Tecnologías de la Información y la Comunicación (TIC) y su aplicación en diversos ámbitos de la vida cotidiana, como el hogar, la educación y el trabajo.
He explicado qué son las TIC, las diferentes categorías y sus respectivos ejemplos, así como los beneficios y aplicaciones en cada uno de estos ámbitos.
Espero que esta información sea útil para quienes la lean y les ayude a comprender mejor las TIC y su impacto en nuestra vida cotidiana.
Todo sobre la tarjeta de video (Bienvenidos a mi blog personal)AbrahamCastillo42
Power point, diseñado por estudiantes de ciclo 1 arquitectura de plataformas, esta con la finalidad de dar a conocer el componente hardware llamado tarjeta de video..
2. El recorrido
● Error y Excepción.
● El excepcionalismo imperativo.
● Encapsular excepciones en Try.
● Errores como parte del dominio.
● Manejo de errores con Scala Either.
● Acumular errores con Validated.
● Reportar errores y aciertos con Ior.
● Conclusiones.
3. Error y Excepción
● Error: resultado no deseado de la evaluación de un programa.
● Excepción: condición excepcional del programa en tiempo de
ejecución.
4. El excepcionalismo imperativo
● Durante la evaluación de un método, si se encuentra un error se arroja
una excepción.
● Este paradigma puede tener su origen en:
○ Lenguajes imperativos sin un sistema de tipos robusto.
○ Considerando lo anterior, carencia de tipos de datos (datatypes) que
permitan manejar los errores.
● Se requiere try/catch para manejar los métodos que puedan arrojar
excepciones.
5. El dominio
case class Book(isbn: String, title: String, author: String, genre: Genre)
trait Genre extends Product with Serializable
object Genre {
case object Fiction extends Genre
case object ScienceFiction extends Genre
case object HistoricNovel extends Genre
case object InvalidGenre extends Genre
}
val theFountainhead = Book("ISBN: 978-1-4028-9462-6","The Fountainhead","Ayn Rand",Genre.Fiction)
val atlasShrugged = Book("ISBN-13 978-1-4028-9462-6","Atlas Shrugged","Ayn Rand",Genre.Fiction)
val theCountOfMontecristo = Book("ISBN-13 978-1-4028-9462","The Count Of Montecristo","Alexandre
Dumas",Genre.HistoricNovel)
val titlelessBook = Book("ISBN-13 978-1-4028-9462-6","","Unknown",Genre.InvalidGenre)
Un libro con isbn, título, autor y género.
6. El excepcionalismo imperativo
private def validateGenre(g: Genre): Unit =
if ( g == Genre.InvalidGenre ) throw new InvalidParameter("Book has invalid genre")
private def validateIsbn(isbn: String): Unit = isbn match {
case isbnRegex(all @ _*) => ()
case _ => throw new InvalidParameter("isbn has not a valid format")
}
private def validateTitle(title: String): Unit =
if (title.isEmpty || title == null) throw new InvalidParameter("title must not be empty")
private def validateAuthor(author: String): Unit =
if (author.isEmpty || author == null) throw new InvalidParameter("author must not be empty")
class InvalidParameter(message: String) extends Exception(message)
class EmptyBookList(message: String) extends Exception(message)
7. El excepcionalismo imperativo
def validateBook(book: Book): Book = {
validateGenre(book.genre)
validateIsbn(book.isbn)
validateTitle(book.title)
validateAuthor(book.author)
book
}
def validateBooks(books: List[Book]): List[Book] =
if (books == Nil) throw new EmptyBookList("Book list was empty")
else {
val booksBuffer = new ListBuffer[Book]
for (book <- books) {
try booksBuffer += validateBook(book) catch { case ex: Exception => println(s"Error $ex") }
}
booksBuffer.toList
}
8. Encapsulando excepciones con Try
● El tipo Try[A] es utilizado para manejar excepciones en métodos.
● Encapsula el resultado en dos subtipos: Success y Failure.
● Success contiene el resultado del método.
● Failure contiene la excepción arrojada.
● Nos permite usar for comprehension.
● Es fail fast en Failure.
9. Encapsulando excepciones con Try
private def validateGenre(g: Genre): Try[Genre] = Try {
g match {
case Genre.InvalidGenre => throw new InvalidParameter("Book has invalid genre")
case genre => genre
}
}
private def validateIsbn(isbn: String): Try[String] = Try {
isbn match {
case isbnRegex(all @ _*) => isbn
case _ => throw new InvalidParameter("isbn has not a valid format")
}
}
private def validateTitle(title: String): Try[String] = Try {
if (Option(title).forall(_.isEmpty)) throw new InvalidParameter("title must not be empty") else title
}
private def validateAuthor(author: String): Try[String] = Try {
if (Option(author).forall(_.isEmpty)) throw new InvalidParameter("author must not be empty") else author
}
10. Encapsulando excepciones con Try
import cats.syntax.semigroup._
//Valida los libros y devuelve una lista no vacía en el caso Success
def validateBook(b: Book): Try[NonEmptyList[Book]] =
for {
i <- validateIsbn(b.isbn)
a <- validateAuthor(b.author)
t <- validateTitle(b.title)
g <- validateGenre(b.genre)
} yield NonEmptyList.of(Book(i, t, a, g))
//Combina los resultados exitosos del Try en una lista no vacía
def validateBooks(bs: List[Book]): Try[NonEmptyList[Book]] = bs match {
case Nil => Failure(new EmptyBookList("Book list was empty"))
case books => books map validateBook reduce (_ |+| _)
}
11. Encapsulando excepciones con Try
"BookValidation" should {
"Validate a book" in {
val validated = validateBook(theFountainhead)
validated should === (Success(NonEmptyList(theFountainhead, Nil)))
}
"Validate books" in {
val validatedBooks = validateBooks(List(theFountainhead, atlasShrugged))
validatedBooks should === (Success(NonEmptyList(theFountainhead, atlasShrugged :: Nil)))
}
"Fail fast error on books" in {
val validatedBooks = validateBooks(List(titlelessBook, theCountOfMontecristo, theFountainhead))
inside(validatedBooks) { case Failure(ex) => ex.getMessage shouldBe "title must not be empty" }
}
}
12. Errores como parte del dominio
● Un error en una función no debe tratarse como algo excepcional.
● Excepciones para interacciones con la capa de infraestructura.
● Excepciones rompen con type safety.
● Los errores también son parte del dominio.
//No es cierto que validateBook siempre devuelve un Book
def validateBook(book: Book): Book = {
validateGenre(book.genre)
validateIsbn(book.isbn)
validateTitle(book.title)
validateAuthor(book.author)
book
}
13. Errores como parte del dominio
sealed trait Error extends Product with Serializable {
val message: String
}
case class InvalidParameter(message: String) extends Error
case class EmptyBookList(message: String) extends Error
Definimos las excepciones anteriormente usadas como ADTs de Error.
14. Manejo de errores con Scala Either
● El tipo Either[A, B] representa el valor de dos tipos posibles: Left o Right
● Convencionalmente se usa el Left para representar errores y Right para
representar los aciertos.
● Nos facilita manejar los errores modelados como parte del dominio.
● Se puede usar for comprehension.
● Es fail fast en Left.
15. Manejo de errores con Scala Either
private def validateGenre(g: Genre): Either[InvalidParameter, Genre] = g match {
case InvalidGenre => Left(InvalidParameter("Book has invalid genre"))
case genre => Right(genre)
}
private def validateIsbn(isbn: String): Either[InvalidParameter, String] = isbn match {
case isbnRegex(all @ _*) => Right(isbn)
case _ => Left(InvalidParameter("isbn has not a valid format"))
}
private def validateTitle(title: String): Either[InvalidParameter, String] =
if (Option(title).forall(_.isEmpty)) Left(InvalidParameter("title must not be empty")) else Right(title)
private def validateAuthor(author: String): Either[InvalidParameter, String] =
if (Option(author).forall(_.isEmpty)) Left(InvalidParameter("author must not be empty")) else Right(author)
16. Manejo de errores con Scala Either
import cats.syntax.semigroup._
//Valida secuencialmente todos los campos, se detiene en el primer error encontrado.
def validateBook(b: Book): Either[InvalidParameter, NonEmptyList[Book]] =
for {
i <- validateIsbn(b.isbn)
a <- validateAuthor(b.author)
t <- validateTitle(b.title)
g <- validateGenre(b.genre)
} yield NonEmptyList.of(Book(i, t, a, g))
//Por ser fail fast, reporta el primer error encontrado pero acumula todos los aciertos.
def validateBooks(bs: List[Book]): Either[Error, NonEmptyList[Book]] = bs match {
case Nil => Left(EmptyBookList("Book list was empty"))
case books => books map validateBook reduce (_ |+| _)
}
17. Manejo de errores con Scala Either
"BookValidation" should {
"Validate a book" in {
val validated = validateBook(theFountainhead)
validated should === (Right(NonEmptyList(theFountainhead, Nil)))
}
"Validate books" in {
val validatedBooks = validateBooks(List(theFountainhead, atlasShrugged))
validatedBooks should === (Right(NonEmptyList(theFountainhead, atlasShrugged :: Nil)))
}
"Fail fast error on books" in {
val validatedBooks = validateBooks(List(titlelessBook, theCountOfMontecristo, theFountainhead))
validatedBooks should === (Left(InvalidParameter("title must not be empty")))
}
}
18. Manejo de errores con Cats Validated
● El tipo Validated[A, B] representa el valor de dos tipos posibles: Valid e
Invalid.
● Desde el punto de vista semántico, es obvio que Invalid es utilizado para
representar los errores y Valid los aciertos.
● Nos facilita manejar los errores modelados como parte del dominio.
● No se puede utilizar en for comprehension.
● Acumula errores en Invalid ( type ValidatedNel[A, B] =
Validated[NonEmptyList[A], B] ).
19. Manejo de errores con Cats Validated
private def validateGenre(g: Genre): ValidatedNel[InvalidParameter, Genre] = g match {
case InvalidGenre => InvalidParameter("Book has invalid genre").invalidNel
case genre => genre.validNel
}
private def validateIsbn(isbn: String): ValidatedNel[InvalidParameter, String] = isbn match {
case isbnRegex(all @ _*) => isbn.validNel
case _ => InvalidParameter("isbn has not a valid format").invalidNel
}
private def validateTitle(title: String): ValidatedNel[InvalidParameter, String] =
if (Option(title).exists(_.isEmpty)) InvalidParameter("title must not be empty").invalidNel else title.validNel
private def validateAuthor(author: String): ValidatedNel[InvalidParameter, String] =
if (Option(author).exists(_.isEmpty)) InvalidParameter("author must not be empty").invalidNel
else author.validNel
20. Manejo de errores con Cats Validated
import cats.syntax.cartesian._
import cats.syntax.semigroup._
//Valida en el producto cartesiano, acumula los errores en cada validación.
def validateBook(b: Book): ValidatedNel[InvalidParameter, NonEmptyList[Book]] = (
validateIsbn(b.isbn) |@|
validateAuthor(b.author) |@|
validateTitle(b.title) |@|
validateGenre(b.genre) ) map {
case (isbn, author, title, genre) =>
NonEmptyList.of(Book(isbn, title, author, genre))
}
//Puede acumular todos los errores o acumular todos los aciertos.
def validateBooks(bs: List[Book]): ValidatedNel[Error, NonEmptyList[Book]] = bs match {
case Nil => EmptyBookList("Book list was empty").invalidNel
case books => books map validateBook reduce (_ |+| _)
}
21. Manejo de errores con Cats Validated
"BookValidation" should {
"Validate books" in {
val validatedBooks = validateBooks(List(theFountainhead, atlasShrugged))
validatedBooks should === (Valid(NonEmptyList(theFountainhead, atlasShrugged :: Nil)))
}
"Accumulate errors on books" in {
val validatedBooks = validateBooks(List(titlelessBook, theCountOfMontecristo, theFountainhead))
validatedBooks should === (
Invalid(
NonEmptyList(InvalidParameter("title must not be empty"),
InvalidParameter("Book has invalid genre") :: InvalidParameter("isbn has not a valid format") :: Nil)
)
)
}
}
22. Manejo de errores con Cats Ior
● El tipo Ior[A, B] representa el valor de tres tipos posibles: Ior.Right,
Ior.Left e Ior.Both.
● La convención con Ior.Left e Ior.Right es igual a la de Either con respecto
a la representación de errores y aciertos.
● Ior.Both permite incluir simultáneamente los errores y aciertos
● Nos facilita manejar los errores modelados como parte del dominio.
● Se puede utilizar en for comprehension.
● Es fail fast en Ior.Left y acumula errores en Ior.Both.
23. Manejo de errores con Cats Ior
private def validateGenre(g: Genre): IorNel[InvalidParameter, Genre] = g match {
case InvalidGenre => Ior.left(NonEmptyList.of(InvalidParameter("Book has invalid genre")))
case genre => Ior.right(genre)
}
private def validateIsbn(isbn: String): IorNel[InvalidParameter, String] = isbn match {
case isbnRegex(all @ _*) => Ior.right(isbn)
case _ => Ior.left(NonEmptyList.of(InvalidParameter("isbn has not a valid format")))
}
private def validateTitle(title: String): IorNel[InvalidParameter, String] =
if (Option(title).exists(_.isEmpty)) Ior.left(NonEmptyList.of(InvalidParameter("title must not be empty")))
else Ior.right(title)
private def validateAuthor(author: String): IorNel[InvalidParameter, String] =
if (Option(author).exists(_.isEmpty)) Ior.left(NonEmptyList.of(InvalidParameter("author must not be empty")))
else Ior.right(author)
24. Manejo de errores con Cats Ior
import cats.syntax.semigroup._
//Valida los campos secuencialmente, se detiene en el primer error.
def validateBook(b: Book): IorNel[InvalidParameter, NonEmptyList[Book]] =
for {
i <- validateIsbn(b.isbn)
a <- validateAuthor(b.author)
t <- validateTitle(b.title)
g <- validateGenre(b.genre)
} yield NonEmptyList.of(Book(i, t, a, g))
//A diferencia de Validated, puede acumular errores y aciertos en Ior.Both
def validateBooks(bs: List[Book]): IorNel[Error, NonEmptyList[Book]] = bs match {
case Nil => Ior.left(EmptyBookList("Book list was empty"))
case books => books map validateBook reduce (_ |+| _)
}
25. Manejo de errores con Cats Ior
"BookValidation" should {
"Validate books" in {
val validatedBooks = validateBooks(List(theFountainhead, atlasShrugged))
validatedBooks should === (Ior.Right(NonEmptyList(theFountainhead, atlasShrugged :: Nil)))
}
"Fail fast error on books" in {
val validatedBooks = validateBooks(List(titlelessBook, theCountOfMontecristo, theFountainhead, atlasShrugged))
validatedBooks should === (
Ior.Both(
NonEmptyList(InvalidParameter("title must not be empty"),InvalidParameter("isbn has not a valid format") :: Nil),
NonEmptyList(theFountainhead, atlasShrugged :: Nil)
)
)
}
}
26. Conclusiones
● En una función no se deben arrojar excepciones, se pierde transparencia
referencial.
● Se favorece la modelación de errores en el dominio.
● Try es fail fast, no es expresivo en cuanto a los errores que encapsula y
se puede usar cuando se depende de métodos de librerías java.
● Either es fail fast y puede acumular aciertos.
● Validated acumula errores, no se puede usar en for comprehensions y
puede acumular aciertos.
● Ior es el más flexible: es fail fast en Ior.Left, acumula errores en Ior.Both y
puede acumular aciertos en Ior.Right e Ior.Both.