The document discusses different approaches to representing data with smart types in Scala to validate data at compile time. It describes using smart constructors with Either types, the Newtype library, and the Refined library to define types for a Person case class that validate fields like names, emails and addresses. Using these approaches helps prevent invalid data from being stored by catching errors at compile time rather than runtime.
Some parts of our applications don't need to be asynchronous or interact with the outside world: it's enough that they are stateful, possibly with the ability to handle failure, context, and logging. Although you can use ZIO 2 or monad transformers for this task, both come with drawbacks. In this presentation, Jorge Vásquez will introduce you to ZPure, a data type from ZIO Prelude, which lets you scale back on the power of ZIO 2, but with the same high-performance, type-inference, and ergonomics you expect from ZIO 2 libraries.
Sometimes we want to keep or collect errors for later examination. We’ll use Cats to help us pick the story we want to tell when handling errors; accumulated errors or first error wins. Monads will be included!
ZIO: Powerful and Principled Functional Programming in ScalaWiem Zine Elabidine
This is an introduction of purely functional programming type safe abstractions that provide a variety of features for building asynchronous and concurrent applications data structures built on ZIO.
You'll learn by examples about the power of functional programming to solve the hard problems of software development in a principled, without compromises.
Some parts of our applications don't need to be asynchronous or interact with the outside world: it's enough that they are stateful, possibly with the ability to handle failure, context, and logging. Although you can use ZIO 2 or monad transformers for this task, both come with drawbacks. In this presentation, Jorge Vásquez will introduce you to ZPure, a data type from ZIO Prelude, which lets you scale back on the power of ZIO 2, but with the same high-performance, type-inference, and ergonomics you expect from ZIO 2 libraries.
Sometimes we want to keep or collect errors for later examination. We’ll use Cats to help us pick the story we want to tell when handling errors; accumulated errors or first error wins. Monads will be included!
ZIO: Powerful and Principled Functional Programming in ScalaWiem Zine Elabidine
This is an introduction of purely functional programming type safe abstractions that provide a variety of features for building asynchronous and concurrent applications data structures built on ZIO.
You'll learn by examples about the power of functional programming to solve the hard problems of software development in a principled, without compromises.
In this core java training session, you will learn Collections – Lists, Sets. Topics covered in this session are:
• List – ArrayList, LinkedList
• Set – HashSet, LinkedHashSet, TreeSet
For more information about this course visit on this link: https://www.mindsmapped.com/courses/software-development/learn-java-fundamentals-hands-on-training-on-core-java-concepts/
non-strict functions, bottom and scala by-name parametersPhilip Schwarz
Download for perfect quality.
Non strict functions, bottom and scala by-name parameters - ‘a close look’, through the work of Runar Bjarnason, Paul Chiusano, Martin Odersky, Bill Venners, Lex Spoon, Alvin Alexander, Mark Lewis and Aleksandar Prokopec.
download for better quality - Learn about the sequence and traverse functions
through the work of Runar Bjarnason and Paul Chiusano, authors of Functional Programming in Scala https://www.manning.com/books/functional-programming-in-scala, and others (Martin Odersky, Derek Wyatt, Adelbert Chang)
Modern applications are concurrent, parallel, asynchronous, and synchronous; they utilize many different subsystems, including network systems, actor systems, distributed systems, and more. Across all these modes of computation and different subsystems, the one constant is failure. Errors happen everywhere, and taming their monstrous complexity in a way that helps developers write correct code and troubleshoot failures is one of the hardest challenges of modern application development.
In this presentation, created just for the Dublin Scala Meetup, John A. De Goes and Kai from 7mind.io will take attendees on a tour of error management in Scala, comparing and contrasting Scala's own Future type, and the ZIO effect type. You'll see how functional effects provide features that go way beyond Future: including unified errors across all modes of computation, powerful error operators, lossless error propagation, compiler-assisted error handling, and a stunning new feature for debugging, sponsored by Irish consultancy 7mind.io, will be unveiled exclusively at this presentation.
Come learn about how modern functional effect systems like ZIO provide compelling new solutions to the problems of everyday error management.
Arrow function expressions are new functions available in ES6. Using arrow function expressions we can reduce function coding. In Arrow function expressions there is no this inside arrow function. if you call this it will take immediate parent's context.
(Video of these slides here http://fsharpforfunandprofit.com/rop)
(My response to "this is just Either" here: http://fsharpforfunandprofit.com/rop/#monads)
Many examples in functional programming assume that you are always on the "happy path". But to create a robust real world application you must deal with validation, logging, network and service errors, and other annoyances.
So, how do you handle all this in a clean functional way? This talk will provide a brief introduction to this topic, using a fun and easy-to-understand railway analogy.
The Functional Programmer's Toolkit (NDC London 2019)Scott Wlaschin
(slides and video at https://fsharpforfunandprofit.com/fptoolkit)
The functional programming community has a number of patterns with strange names such as monads, monoids, functors, and catamorphisms.
In this beginner-friendly talk, we'll demystify these techniques and see how they all fit together into a small but versatile "tool kit".
We'll then see how the tools in this tool kit can be applied to a wide variety of programming problems, such as handling missing data, working with lists, and implementing the functional equivalent of dependency injection.
Functional programming can be an excellent approach to designing decoupled, reusable systems with a rich domain model. In fact, the lessons from applying DDD in a functional language translate well to object-oriented programming.
You may be hearing a lot of buzz around functional programming. For example, Java 8 recently introduced new features (lambda expressions and method references) and APIs (Streams, Optional and CompletableFutures) inspired from functional ideas such as first-class functions, composition and immutability.
However, what does this mean for my existing codebase?
In this talk we show how you can refactor your traditional object-oriented Java to using FP features and APIs from Java 8 in a beneficial manner.
We will discuss:
- How to adapt to requirement changes using first-class functions
- How you can enhance code reusability using currying
- How you can make your code more robust by favouring immutability over mutability
- How you can design better APIs and reduce unintended null pointer exceptions using an optional data type"
In this core java training session, you will learn Collections – Lists, Sets. Topics covered in this session are:
• List – ArrayList, LinkedList
• Set – HashSet, LinkedHashSet, TreeSet
For more information about this course visit on this link: https://www.mindsmapped.com/courses/software-development/learn-java-fundamentals-hands-on-training-on-core-java-concepts/
non-strict functions, bottom and scala by-name parametersPhilip Schwarz
Download for perfect quality.
Non strict functions, bottom and scala by-name parameters - ‘a close look’, through the work of Runar Bjarnason, Paul Chiusano, Martin Odersky, Bill Venners, Lex Spoon, Alvin Alexander, Mark Lewis and Aleksandar Prokopec.
download for better quality - Learn about the sequence and traverse functions
through the work of Runar Bjarnason and Paul Chiusano, authors of Functional Programming in Scala https://www.manning.com/books/functional-programming-in-scala, and others (Martin Odersky, Derek Wyatt, Adelbert Chang)
Modern applications are concurrent, parallel, asynchronous, and synchronous; they utilize many different subsystems, including network systems, actor systems, distributed systems, and more. Across all these modes of computation and different subsystems, the one constant is failure. Errors happen everywhere, and taming their monstrous complexity in a way that helps developers write correct code and troubleshoot failures is one of the hardest challenges of modern application development.
In this presentation, created just for the Dublin Scala Meetup, John A. De Goes and Kai from 7mind.io will take attendees on a tour of error management in Scala, comparing and contrasting Scala's own Future type, and the ZIO effect type. You'll see how functional effects provide features that go way beyond Future: including unified errors across all modes of computation, powerful error operators, lossless error propagation, compiler-assisted error handling, and a stunning new feature for debugging, sponsored by Irish consultancy 7mind.io, will be unveiled exclusively at this presentation.
Come learn about how modern functional effect systems like ZIO provide compelling new solutions to the problems of everyday error management.
Arrow function expressions are new functions available in ES6. Using arrow function expressions we can reduce function coding. In Arrow function expressions there is no this inside arrow function. if you call this it will take immediate parent's context.
(Video of these slides here http://fsharpforfunandprofit.com/rop)
(My response to "this is just Either" here: http://fsharpforfunandprofit.com/rop/#monads)
Many examples in functional programming assume that you are always on the "happy path". But to create a robust real world application you must deal with validation, logging, network and service errors, and other annoyances.
So, how do you handle all this in a clean functional way? This talk will provide a brief introduction to this topic, using a fun and easy-to-understand railway analogy.
The Functional Programmer's Toolkit (NDC London 2019)Scott Wlaschin
(slides and video at https://fsharpforfunandprofit.com/fptoolkit)
The functional programming community has a number of patterns with strange names such as monads, monoids, functors, and catamorphisms.
In this beginner-friendly talk, we'll demystify these techniques and see how they all fit together into a small but versatile "tool kit".
We'll then see how the tools in this tool kit can be applied to a wide variety of programming problems, such as handling missing data, working with lists, and implementing the functional equivalent of dependency injection.
Functional programming can be an excellent approach to designing decoupled, reusable systems with a rich domain model. In fact, the lessons from applying DDD in a functional language translate well to object-oriented programming.
You may be hearing a lot of buzz around functional programming. For example, Java 8 recently introduced new features (lambda expressions and method references) and APIs (Streams, Optional and CompletableFutures) inspired from functional ideas such as first-class functions, composition and immutability.
However, what does this mean for my existing codebase?
In this talk we show how you can refactor your traditional object-oriented Java to using FP features and APIs from Java 8 in a beneficial manner.
We will discuss:
- How to adapt to requirement changes using first-class functions
- How you can enhance code reusability using currying
- How you can make your code more robust by favouring immutability over mutability
- How you can design better APIs and reduce unintended null pointer exceptions using an optional data type"
Scala er et Java-relateret, statisk typet programmeringssprog i hastig fremmarch. Sproget kombinerer aspekter fra objekt- og funktionsorienterede sprog og fokuserer på skalerbarhed og effektivitet, både på det kodemæssige og afviklingsmæssige niveau. Syntaksen er elegant og koncis. Samtidig indeholder sproget stærke konstruktioner til understøttelse af parallelle applikationer, der udnytter fremtidens hardwarearkitekturer.
Scala er et Java-relateret, statisk typet programmeringssprog i hastig fremmarch. Sproget kombinerer aspekter fra objekt- og funktionsorienterede sprog og fokuserer på skalerbarhed og effektivitet, både på det kodemæssige og afviklingsmæssige niveau. Syntaksen er elegant og koncis. Samtidig indeholder sproget stærke konstruktioner til understøttelse af parallelle applikationer, der udnytter fremtidens hardwarearkitekturer.
Java som sprog har ikke bevæget sig meget de seneste år. Vi har stadig ikke closures eller funktionelle aspekter som f.eks. C# har haft siden version 3. Er Scala svaret på enhver Javaudviklers bønner eller er sproget kun interessant for tågehoveder som mig, som begynder at synes bedre og bedre om funktionsorientering? Er den store portion syntaktisk sukker, Scala bringer på bordet, bare tomme kalorier?
The need for functional programming languages is more important than ever with the current hardware and software trends. Scala has become the number one choice for functional programming languages and is becoming the language of choice for many development teams. But with the introduction of functional programming in Java 8 is Scala still relevant and needed?
These are the slides of the second part of this multi-part series, from Learn Python Den Haag meetup group. It covers List comprehensions, Dictionary comprehensions and functions.
May Marketo Masterclass, London MUG May 22 2024.pdfAdele Miller
Can't make Adobe Summit in Vegas? No sweat because the EMEA Marketo Engage Champions are coming to London to share their Summit sessions, insights and more!
This is a MUG with a twist you don't want to miss.
Code reviews are vital for ensuring good code quality. They serve as one of our last lines of defense against bugs and subpar code reaching production.
Yet, they often turn into annoying tasks riddled with frustration, hostility, unclear feedback and lack of standards. How can we improve this crucial process?
In this session we will cover:
- The Art of Effective Code Reviews
- Streamlining the Review Process
- Elevating Reviews with Automated Tools
By the end of this presentation, you'll have the knowledge on how to organize and improve your code review proces
Cyaniclab : Software Development Agency Portfolio.pdfCyanic lab
CyanicLab, an offshore custom software development company based in Sweden,India, Finland, is your go-to partner for startup development and innovative web design solutions. Our expert team specializes in crafting cutting-edge software tailored to meet the unique needs of startups and established enterprises alike. From conceptualization to execution, we offer comprehensive services including web and mobile app development, UI/UX design, and ongoing software maintenance. Ready to elevate your business? Contact CyanicLab today and let us propel your vision to success with our top-notch IT solutions.
Unleash Unlimited Potential with One-Time Purchase
BoxLang is more than just a language; it's a community. By choosing a Visionary License, you're not just investing in your success, you're actively contributing to the ongoing development and support of BoxLang.
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Globus
Large Language Models (LLMs) are currently the center of attention in the tech world, particularly for their potential to advance research. In this presentation, we'll explore a straightforward and effective method for quickly initiating inference runs on supercomputers using the vLLM tool with Globus Compute, specifically on the Polaris system at ALCF. We'll begin by briefly discussing the popularity and applications of LLMs in various fields. Following this, we will introduce the vLLM tool, and explain how it integrates with Globus Compute to efficiently manage LLM operations on Polaris. Attendees will learn the practical aspects of setting up and remotely triggering LLMs from local machines, focusing on ease of use and efficiency. This talk is ideal for researchers and practitioners looking to leverage the power of LLMs in their work, offering a clear guide to harnessing supercomputing resources for quick and effective LLM inference.
Experience our free, in-depth three-part Tendenci Platform Corporate Membership Management workshop series! In Session 1 on May 14th, 2024, we began with an Introduction and Setup, mastering the configuration of your Corporate Membership Module settings to establish membership types, applications, and more. Then, on May 16th, 2024, in Session 2, we focused on binding individual members to a Corporate Membership and Corporate Reps, teaching you how to add individual members and assign Corporate Representatives to manage dues, renewals, and associated members. Finally, on May 28th, 2024, in Session 3, we covered questions and concerns, addressing any queries or issues you may have.
For more Tendenci AMS events, check out www.tendenci.com/events
Into the Box Keynote Day 2: Unveiling amazing updates and announcements for modern CFML developers! Get ready for exciting releases and updates on Ortus tools and products. Stay tuned for cutting-edge innovations designed to boost your productivity.
In software engineering, the right architecture is essential for robust, scalable platforms. Wix has undergone a pivotal shift from event sourcing to a CRUD-based model for its microservices. This talk will chart the course of this pivotal journey.
Event sourcing, which records state changes as immutable events, provided robust auditing and "time travel" debugging for Wix Stores' microservices. Despite its benefits, the complexity it introduced in state management slowed development. Wix responded by adopting a simpler, unified CRUD model. This talk will explore the challenges of event sourcing and the advantages of Wix's new "CRUD on steroids" approach, which streamlines API integration and domain event management while preserving data integrity and system resilience.
Participants will gain valuable insights into Wix's strategies for ensuring atomicity in database updates and event production, as well as caching, materialization, and performance optimization techniques within a distributed system.
Join us to discover how Wix has mastered the art of balancing simplicity and extensibility, and learn how the re-adoption of the modest CRUD has turbocharged their development velocity, resilience, and scalability in a high-growth environment.
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Mind IT Systems
Healthcare providers often struggle with the complexities of chronic conditions and remote patient monitoring, as each patient requires personalized care and ongoing monitoring. Off-the-shelf solutions may not meet these diverse needs, leading to inefficiencies and gaps in care. It’s here, custom healthcare software offers a tailored solution, ensuring improved care and effectiveness.
Software Engineering, Software Consulting, Tech Lead.
Spring Boot, Spring Cloud, Spring Core, Spring JDBC, Spring Security,
Spring Transaction, Spring MVC,
Log4j, REST/SOAP WEB-SERVICES.
Enhancing Research Orchestration Capabilities at ORNL.pdfGlobus
Cross-facility research orchestration comes with ever-changing constraints regarding the availability and suitability of various compute and data resources. In short, a flexible data and processing fabric is needed to enable the dynamic redirection of data and compute tasks throughout the lifecycle of an experiment. In this talk, we illustrate how we easily leveraged Globus services to instrument the ACE research testbed at the Oak Ridge Leadership Computing Facility with flexible data and task orchestration capabilities.
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTier1 app
Even though at surface level ‘java.lang.OutOfMemoryError’ appears as one single error; underlyingly there are 9 types of OutOfMemoryError. Each type of OutOfMemoryError has different causes, diagnosis approaches and solutions. This session equips you with the knowledge, tools, and techniques needed to troubleshoot and conquer OutOfMemoryError in all its forms, ensuring smoother, more efficient Java applications.
top nidhi software solution freedownloadvrstrong314
This presentation emphasizes the importance of data security and legal compliance for Nidhi companies in India. It highlights how online Nidhi software solutions, like Vector Nidhi Software, offer advanced features tailored to these needs. Key aspects include encryption, access controls, and audit trails to ensure data security. The software complies with regulatory guidelines from the MCA and RBI and adheres to Nidhi Rules, 2014. With customizable, user-friendly interfaces and real-time features, these Nidhi software solutions enhance efficiency, support growth, and provide exceptional member services. The presentation concludes with contact information for further inquiries.
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Globus
The Earth System Grid Federation (ESGF) is a global network of data servers that archives and distributes the planet’s largest collection of Earth system model output for thousands of climate and environmental scientists worldwide. Many of these petabyte-scale data archives are located in proximity to large high-performance computing (HPC) or cloud computing resources, but the primary workflow for data users consists of transferring data, and applying computations on a different system. As a part of the ESGF 2.0 US project (funded by the United States Department of Energy Office of Science), we developed pre-defined data workflows, which can be run on-demand, capable of applying many data reduction and data analysis to the large ESGF data archives, transferring only the resultant analysis (ex. visualizations, smaller data files). In this talk, we will showcase a few of these workflows, highlighting how Globus Flows can be used for petabyte-scale climate analysis.
How to Position Your Globus Data Portal for Success Ten Good PracticesGlobus
Science gateways allow science and engineering communities to access shared data, software, computing services, and instruments. Science gateways have gained a lot of traction in the last twenty years, as evidenced by projects such as the Science Gateways Community Institute (SGCI) and the Center of Excellence on Science Gateways (SGX3) in the US, The Australian Research Data Commons (ARDC) and its platforms in Australia, and the projects around Virtual Research Environments in Europe. A few mature frameworks have evolved with their different strengths and foci and have been taken up by a larger community such as the Globus Data Portal, Hubzero, Tapis, and Galaxy. However, even when gateways are built on successful frameworks, they continue to face the challenges of ongoing maintenance costs and how to meet the ever-expanding needs of the community they serve with enhanced features. It is not uncommon that gateways with compelling use cases are nonetheless unable to get past the prototype phase and become a full production service, or if they do, they don't survive more than a couple of years. While there is no guaranteed pathway to success, it seems likely that for any gateway there is a need for a strong community and/or solid funding streams to create and sustain its success. With over twenty years of examples to draw from, this presentation goes into detail for ten factors common to successful and enduring gateways that effectively serve as best practices for any new or developing gateway.
Check out the webinar slides to learn more about how XfilesPro transforms Salesforce document management by leveraging its world-class applications. For more details, please connect with sales@xfilespro.com
If you want to watch the on-demand webinar, please click here: https://www.xfilespro.com/webinars/salesforce-document-management-2-0-smarter-faster-better/
4. Background
ZIO Prelude is a Scala-first take on functional abstractions
• Type classes to describe the ways different types are
similar
5. Background
ZIO Prelude is a Scala-first take on functional abstractions
• Type classes to describe the ways different types are
similar
• Data types that complement the Scala standard library
(NonEmptyList, ZValidation, ZPure)
6. Background
ZIO Prelude is a Scala-first take on functional abstractions
• Type classes to describe the ways different types are
similar
• Data types that complement the Scala standard library
(NonEmptyList, ZValidation, ZPure)
• Smart Types
17. Smart Constructors
final case class Name private (name: String)
object Name {
def make(value: String): Either[String, Name] =
if (value.nonEmpty) Right(Name(value))
else Left("Name cannot be empty")
}
18. Smart Constructors
final case class Name private (name: String)
object Name {
def make(value: String): Either[String, Name] =
if (value.nonEmpty) Right(Name(value))
else Left("Name cannot be empty")
}
19. Smart Constructors
final case class Name private (name: String)
object Name {
def make(value: String): Either[String, Name] =
if (value.nonEmpty) Right(Name(value))
else Left("Name cannot be empty")
}
20. Smart Constructors
final case class Name private (name: String)
object Name {
def make(value: String): Either[String, Name] =
if (value.nonEmpty) Right(Name(value))
else Left("Name cannot be empty")
}
21. Smart Constructors
final case class Email private (email: String)
object Email {
def make(value: String): Either[String, Email] = {
val regex = "^[w-.]+@([w-]+.)+[w-]{2,4}$"
if (value.matches(regex)) Right(Email(value))
else Left(s"$value does not match $regex")
}
}
22. Smart Constructors
final case class Address private (address: String)
object Address {
def make(value: String): Either[String, Address] =
if (value.nonEmpty) Right(Address(value))
else Left("Address cannot be empty")
}
final case class Person(name: Name, email: Email, address: Address)
23. Smart Constructors
final case class Address private (address: String)
object Address {
def make(value: String): Either[String, Address] =
if (value.nonEmpty) Right(Address(value))
else Left("Address cannot be empty")
}
final case class Person(name: Name, email: Email, address: Address)
24. Smart Constructors
final case class Address private (address: String)
object Address {
def make(value: String): Either[String, Address] =
if (value.nonEmpty) Right(Address(value))
else Left("Address cannot be empty")
}
final case class Person(name: Name, email: Email, address: Address)
25.
26.
27. Smart Constructors
val person: Either[String, Person] =
for {
name <- Name.make("Jorge")
email <- Email.make("jorge.vasquez@scalac.io")
address <- Address.make("100 Some St.")
} yield Person(name, email, address)
28. Smart Constructors
val person: Either[String, Person] =
for {
name <- Name.make("Jorge")
email <- Email.make("jorge.vasquez@scalac.io")
address <- Address.make("100 Some St.")
} yield Person(name, email, address)
29. Smart Constructors
val person: Either[String, Person] =
for {
name <- Name.make("Jorge")
email <- Email.make("jorge.vasquez@scalac.io")
address <- Address.make("100 Some St.")
} yield Person(name, email, address)
30. Smart Constructors
val person: Either[String, Person] =
for {
name <- Name.make("Jorge")
email <- Email.make("jorge.vasquez@scalac.io")
address <- Address.make("100 Some St.")
} yield Person(name, email, address)
31. Smart Constructors
val person: Either[String, Person] =
for {
name <- Name.make("Jorge")
email <- Email.make("jorge.vasquez@scalac.io")
address <- Address.make("100 Some St.")
} yield Person(name, email, address)
32. Smart Constructors
val person: Either[String, Person] =
for {
name <- Name.make("Jorge")
email <- Email.make("jorge.vasquez@scalac.io")
address <- Address.make("100 Some St.")
} yield Person(name, email, address)
33. Smart Constructors
val person: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
34. Smart Constructors
val person: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
35. Smart Constructors
val person: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
36. Smart Constructors
val person: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
37. Smart Constructors
val person: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
38. Smart Constructors
val person: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
39.
40. Using the Newtype library
import io.estatico.newtype.macros.newtype
import io.estatico.newtype.ops._
@newtype class Name(name: String)
object Name {
def make(value: String): Either[String, Name] =
if (value.nonEmpty) Right(value.coerce)
else Left("Name cannot be empty")
}
41. Using the Newtype library
import io.estatico.newtype.macros.newtype
import io.estatico.newtype.ops._
@newtype class Email(email: String)
object Email {
def make(value: String): Either[String, Email] = {
val regex = "^[w-.]+@([w-]+.)+[w-]{2,4}$"
if (value.matches(regex)) Right(value.coerce)
else Left(s"$value does not match $regex")
}
}
42. Using the Newtype library
import io.estatico.newtype.macros.newtype
import io.estatico.newtype.ops._
@newtype class Address(address: String)
object Address {
def make(value: String): Either[String, Address] =
if (value.nonEmpty) Right(value.coerce)
else Left("Address cannot be empty")
}
final case class Person(name: Name, email: Email, address: Address)
43. Using the Newtype library
import io.estatico.newtype.macros.newtype
import io.estatico.newtype.ops._
@newtype class Address(address: String)
object Address {
def make(value: String): Either[String, Address] =
if (value.nonEmpty) Right(value.coerce)
else Left("Address cannot be empty")
}
final case class Person(name: Name, email: Email, address: Address)
44. Using the Newtype library
import io.estatico.newtype.macros.newtype
import io.estatico.newtype.ops._
@newtype class Address(address: String)
object Address {
def make(value: String): Either[String, Address] =
if (value.nonEmpty) Right(value.coerce)
else Left("Address cannot be empty")
}
final case class Person(name: Name, email: Email, address: Address)
45.
46. Newtype library
val person: Either[String, Person] =
for {
name <- Name.make("Jorge")
email <- Email.make("jorge.vasquez@scalac.io")
address <- Address.make("100 Some St.")
} yield Person(name, email, address)
47. Newtype library
val person: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
48.
49. Using the Refined library
import eu.timepit.refined._
import eu.timepit.refined.api.Refined
import eu.timepit.refined.auto._
import eu.timepit.refined.collection._
import eu.timepit.refined.string._
type Name = String Refined NonEmpty
type Email = String Refined MatchesRegex["^[w-.]+@([w-]+.)+[w-]{2,4}$"] // This works since Scala 2.13 thanks to literal types
type Email = String Refined MatchesRegex[W.`^[w-.]+@([w-]+.)+[w-]{2,4}$`.T] // Before Scala 2.13
type Address = String Refined NonEmpty
final case class Person(name: Name, email: Email, address: Address)
50. Using the Refined library
import eu.timepit.refined._
import eu.timepit.refined.api.Refined
import eu.timepit.refined.auto._
import eu.timepit.refined.collection._
import eu.timepit.refined.string._
type Name = String Refined NonEmpty
type Email = String Refined MatchesRegex["^[w-.]+@([w-]+.)+[w-]{2,4}$"] // This works since Scala 2.13 thanks to literal types
type Email = String Refined MatchesRegex[W.`^[w-.]+@([w-]+.)+[w-]{2,4}$`.T] // Before Scala 2.13
type Address = String Refined NonEmpty
final case class Person(name: Name, email: Email, address: Address)
51. Using the Refined library
import eu.timepit.refined._
import eu.timepit.refined.api.Refined
import eu.timepit.refined.auto._
import eu.timepit.refined.collection._
import eu.timepit.refined.string._
type Name = String Refined NonEmpty
type Email = String Refined MatchesRegex["^[w-.]+@([w-]+.)+[w-]{2,4}$"] // This works since Scala 2.13 thanks to literal types
type Email = String Refined MatchesRegex[W.`^[w-.]+@([w-]+.)+[w-]{2,4}$`.T] // Before Scala 2.13
type Address = String Refined NonEmpty
final case class Person(name: Name, email: Email, address: Address)
52. Using the Refined library
import eu.timepit.refined._
import eu.timepit.refined.api.Refined
import eu.timepit.refined.auto._
import eu.timepit.refined.collection._
import eu.timepit.refined.string._
type Name = String Refined NonEmpty
type Email = String Refined MatchesRegex["^[w-.]+@([w-]+.)+[w-]{2,4}$"] // This works since Scala 2.13 thanks to literal types
type Email = String Refined MatchesRegex[W.`^[w-.]+@([w-]+.)+[w-]{2,4}$`.T] // Before Scala 2.13
type Address = String Refined NonEmpty
final case class Person(name: Name, email: Email, address: Address)
53. Using the Refined library
import eu.timepit.refined._
import eu.timepit.refined.api.Refined
import eu.timepit.refined.auto._
import eu.timepit.refined.collection._
import eu.timepit.refined.string._
type Name = String Refined NonEmpty
type Email = String Refined MatchesRegex["^[w-.]+@([w-]+.)+[w-]{2,4}$"] // This works since Scala 2.13 thanks to literal types
type Email = String Refined MatchesRegex[W.`^[w-.]+@([w-]+.)+[w-]{2,4}$`.T] // Before Scala 2.13
type Address = String Refined NonEmpty
final case class Person(name: Name, email: Email, address: Address)
54. Using the Refined library
import eu.timepit.refined._
import eu.timepit.refined.api.Refined
import eu.timepit.refined.auto._
import eu.timepit.refined.collection._
import eu.timepit.refined.string._
type Name = String Refined NonEmpty
type Email = String Refined MatchesRegex["^[w-.]+@([w-]+.)+[w-]{2,4}$"] // This works since Scala 2.13 thanks to literal types
type Email = String Refined MatchesRegex[W.`^[w-.]+@([w-]+.)+[w-]{2,4}$`.T] // Before Scala 2.13
type Address = String Refined NonEmpty
final case class Person(name: Name, email: Email, address: Address)
55. Compile-time
validations with
Refined
val name1: Name = "Jorge"
val email1: Email = "jorge.vasquez@scalac.io"
val address1: Address = "100 Some St."
val person1: Person = Person(name1, email1, address1)
56. Compile-time
validations with
Refined
val name1: Name = "Jorge"
val email1: Email = "jorge.vasquez@scalac.io"
val address1: Address = "100 Some St."
val person1: Person = Person(name1, email1, address1)
57. Compile-time
validations with
Refined
val name1: Name = "Jorge"
val email1: Email = "jorge.vasquez@scalac.io"
val address1: Address = "100 Some St."
val person1: Person = Person(name1, email1, address1)
58. Compile-time
validations with
Refined
val name1: Name = "Jorge"
val email1: Email = "jorge.vasquez@scalac.io"
val address1: Address = "100 Some St."
val person1: Person = Person(name1, email1, address1)
59. Compile-time
validations with
Refined
val name1: Name = "Jorge"
val email1: Email = "jorge.vasquez@scalac.io"
val address1: Address = "100 Some St."
val person1: Person = Person(name1, email1, address1)
60. Compile-time
validations with
Refined
val name2: Name = ""
// Predicate isEmpty() did not fail
val email2: Email = "whatever"
// Predicate failed:
// "whatever".matches("^[w-.]+@([w-]+.)+[w-]{2,4}$").
val address2: Address = ""
// Predicate isEmpty() did not fail
val person2: Person = Person(name2, email2, address2)
61. Compile-time
validations with
Refined
val name2: Name = ""
// Predicate isEmpty() did not fail
val email2: Email = "whatever"
// Predicate failed:
// "whatever".matches("^[w-.]+@([w-]+.)+[w-]{2,4}$").
val address2: Address = ""
// Predicate isEmpty() did not fail
val person2: Person = Person(name2, email2, address2)
62. Compile-time
validations with
Refined
val name2: Name = ""
// Predicate isEmpty() did not fail
val email2: Email = "whatever"
// Predicate failed:
// "whatever".matches("^[w-.]+@([w-]+.)+[w-]{2,4}$").
val address2: Address = ""
// Predicate isEmpty() did not fail
val person2: Person = Person(name2, email2, address2)
63. Compile-time
validations with
Refined
val name2: Name = ""
// Predicate isEmpty() did not fail
val email2: Email = "whatever"
// Predicate failed:
// "whatever".matches("^[w-.]+@([w-]+.)+[w-]{2,4}$").
val address2: Address = ""
// Predicate isEmpty() did not fail
val person2: Person = Person(name2, email2, address2)
64. Compile-time
validations with
Refined
val name2: Name = ""
// Predicate isEmpty() did not fail
val email2: Email = "whatever"
// Predicate failed:
// "whatever".matches("^[w-.]+@([w-]+.)+[w-]{2,4}$").
val address2: Address = ""
// Predicate isEmpty() did not fail
val person2: Person = Person(name2, email2, address2)
68. Runtime validations
with Refined
val name3: Either[String, Name] =
refineV(scala.io.StdIn.readLine())
val email3: Either[String, Email] =
refineV(scala.io.StdIn.readLine())
val address3: Either[String, Address] =
refineV(scala.io.StdIn.readLine())
val person3a: Either[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
69. Runtime validations
with Refined
val name3: Either[String, Name] =
refineV(scala.io.StdIn.readLine())
val email3: Either[String, Email] =
refineV(scala.io.StdIn.readLine())
val address3: Either[String, Address] =
refineV(scala.io.StdIn.readLine())
val person3a: Either[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
70. Runtime validations
with Refined
val name3: Either[String, Name] =
refineV(scala.io.StdIn.readLine())
val email3: Either[String, Email] =
refineV(scala.io.StdIn.readLine())
val address3: Either[String, Address] =
refineV(scala.io.StdIn.readLine())
val person3a: Either[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
71. Runtime validations
with Refined
val name3: Either[String, Name] =
refineV(scala.io.StdIn.readLine())
val email3: Either[String, Email] =
refineV(scala.io.StdIn.readLine())
val address3: Either[String, Address] =
refineV(scala.io.StdIn.readLine())
val person3a: Either[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
72. Runtime validations
with Refined
val name3: Either[String, Name] =
refineV(scala.io.StdIn.readLine())
val email3: Either[String, Email] =
refineV(scala.io.StdIn.readLine())
val address3: Either[String, Address] =
refineV(scala.io.StdIn.readLine())
val person3a: Either[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
73. Runtime validations
with Refined
val name3: Either[String, Name] =
refineV(scala.io.StdIn.readLine())
val email3: Either[String, Email] =
refineV(scala.io.StdIn.readLine())
val address3: Either[String, Address] =
refineV(scala.io.StdIn.readLine())
val person3b: Either[String, Person] =
for {
name <- address3
email <- email3
address <- name3
} yield Person(name, email, address)
74.
75. Refined with Smart Constructors!
final case class Name(name: String Refined NonEmpty)
object Name {
def make(value: String): Either[String, Name] = refineV[NonEmpty](value).map(Name(_))
}
76. Refined with Smart Constructors!
type EmailRegex = MatchesRegex["^[w-.]+@([w-]+.)+[w-]{2,4}$"]
final case class Email(email: String Refined EmailRegex)
object Email {
def make(value: String): Either[String, Email] =
refineV[EmailRegex](value).map(Email(_))
}
77. Refined with Smart Constructors!
final case class Address(address: String Refined NonEmpty)
object Address {
def make(value: String): Either[String, Address] = refineV[NonEmpty](value).map(Address(_))
}
final case class Person(name: Name, email: Email, address: Address)
78. Refined with Smart Constructors!
final case class Address(address: String Refined NonEmpty)
object Address {
def make(value: String): Either[String, Address] = refineV[NonEmpty](value).map(Address(_))
}
final case class Person(name: Name, email: Email, address: Address)
79. Refined with Smart
Constructors!
val name1: Name = Name("Jorge")
val email1: Email = Email("jorge.vasquez@scalac.io")
val address1: Address = Address("100 Some St.")
val person1: Person = Person(name1, email1, address1)
80. Refined with Smart
Constructors!
val name1: Name = Name("Jorge")
val email1: Email = Email("jorge.vasquez@scalac.io")
val address1: Address = Address("100 Some St.")
val person1: Person = Person(name1, email1, address1)
81. Refined with Smart
Constructors!
val name1: Name = Name("Jorge")
val email1: Email = Email("jorge.vasquez@scalac.io")
val address1: Address = Address("100 Some St.")
val person1: Person = Person(name1, email1, address1)
82. Refined with Smart
Constructors!
val name1: Name = Name("Jorge")
val email1: Email = Email("jorge.vasquez@scalac.io")
val address1: Address = Address("100 Some St.")
val person1: Person = Person(name1, email1, address1)
83. Refined with Smart
Constructors!
val name1: Name = Name("Jorge")
val email1: Email = Email("jorge.vasquez@scalac.io")
val address1: Address = Address("100 Some St.")
val person1: Person = Person(name1, email1, address1)
84. Refined with Smart
Constructors!
val name2: Either[String, Name] =
Name.make(scala.io.StdIn.readLine())
val email2: Either[String, Email] =
Email.make(scala.io.StdIn.readLine())
val address2: Either[String, Address] =
Address.make(scala.io.StdIn.readLine())
val person2a: Either[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
85. Refined with Smart
Constructors!
val name2: Either[String, Name] =
Name.make(scala.io.StdIn.readLine())
val email2: Either[String, Email] =
Email.make(scala.io.StdIn.readLine())
val address2: Either[String, Address] =
Address.make(scala.io.StdIn.readLine())
val person2a: Either[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
86. Refined with Smart
Constructors!
val name2: Either[String, Name] =
Name.make(scala.io.StdIn.readLine())
val email2: Either[String, Email] =
Email.make(scala.io.StdIn.readLine())
val address2: Either[String, Address] =
Address.make(scala.io.StdIn.readLine())
val person2a: Either[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
87. Refined with Smart
Constructors!
val name2: Either[String, Name] =
Name.make(scala.io.StdIn.readLine())
val email2: Either[String, Email] =
Email.make(scala.io.StdIn.readLine())
val address2: Either[String, Address] =
Address.make(scala.io.StdIn.readLine())
val person2a: Either[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
88. Refined with Smart
Constructors!
val name2: Either[String, Name] =
Name.make(scala.io.StdIn.readLine())
val email2: Either[String, Email] =
Email.make(scala.io.StdIn.readLine())
val address2: Either[String, Address] =
Address.make(scala.io.StdIn.readLine())
val person2a: Either[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
89. Refined with Smart
Constructors!
val person2b: Either[String, Person] =
for {
name <- address2 // Expected Name, found Address
email <- email2
address <- name2 // Expected Address, found Name
} yield Person(name, email, address)
90. Refined with Smart
Constructors!
val person2b: Either[String, Person] =
for {
name <- address2 // Expected Name, found Address
email <- email2
address <- name2 // Expected Address, found Name
} yield Person(name, email, address)
91.
92.
93.
94. Opaque types +
Smart Constructors
(Scala 3)
opaque type Name = String
object Name:
def make(value: String): Either[String, Name] =
if value.nonEmpty then Right(value)
else Left("Name cannot be empty")
95. Opaque types +
Smart Constructors
(Scala 3)
opaque type Email = String
object Email:
def make(value: String): Either[String, Email] =
val regex = "^[w-.]+@([w-]+.)+[w-]{2,4}$"
if value.matches(regex) then Right(value)
else Left(s"$value does not match $regex")
96. Opaque types +
Smart Constructors
(Scala 3)
opaque type Address = String
object Address:
def make(value: String): Either[String, Address] =
if value.nonEmpty then Right(value)
else Left("Address cannot be empty")
final case class Person(name: Name, email: Email, address: Address)
97. Opaque types +
Smart Constructors
(Scala 3)
opaque type Address = String
object Address:
def make(value: String): Either[String, Address] =
if value.nonEmpty then Right(value)
else Left("Address cannot be empty")
final case class Person(name: Name, email: Email, address: Address)
98. Opaque types +
Smart Constructors
(Scala 3)
opaque type Address = String
object Address:
def make(value: String): Either[String, Address] =
if value.nonEmpty then Right(value)
else Left("Address cannot be empty")
final case class Person(name: Name, email: Email, address: Address)
99.
100. Opaque types +
Smart Constructors
(Scala 3)
val person: Either[String, Person] =
for
name <- Name.make("Jorge")
email <- Email.make("jorge.vasquez@scalac.io")
address <- Address.make("100 Some St.")
yield Person(name, email, address)
101. Opaque types +
Smart Constructors
(Scala 3)
val person: Either[String, Person] =
for
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
yield Person(name, email, address)
102.
103.
104. Wouldn't it be great if we could
have more precise data
modelling, without unnecessary
overhead at compile-time AND
at runtime?
131. Compile-time validations
val name1: Name = Name("Jorge")
val email1: Email = Email("jorge.vasquez@scalac.io")
val address1: Address = Address("100 Some St.")
val person1: Person = Person(name1, email1, address1)
132. Compile-time validations
val name1: Name = Name("Jorge")
val email1: Email = Email("jorge.vasquez@scalac.io")
val address1: Address = Address("100 Some St.")
val person1: Person = Person(name1, email1, address1)
133. Compile-time validations
val name1: Name = Name("Jorge")
val email1: Email = Email("jorge.vasquez@scalac.io")
val address1: Address = Address("100 Some St.")
val person1: Person = Person(name1, email1, address1)
134. Compile-time validations
val name1: Name = Name("Jorge")
val email1: Email = Email("jorge.vasquez@scalac.io")
val address1: Address = Address("100 Some St.")
val person1: Person = Person(name1, email1, address1)
135. Compile-time validations
val name1: Name = Name("Jorge")
val email1: Email = Email("jorge.vasquez@scalac.io")
val address1: Address = Address("100 Some St.")
val person1: Person = Person(name1, email1, address1)
136. Compile-time validations
val name2: Name = Name("") // COMPILATION ERROR! did not satisfy hasLength(notEqualTo(0))
val email2: Email = Email("whatever") // COMPILATION ERROR! did not satisfy matches(^([w-.])*@([w-])*(.)*([w-]){2,4}$)
val address2: Address = Address("") // COMPILATION ERROR! did not satisfy hasLength(notEqualTo(0))
val person2: Person = Person(name2, email2, address2)
137. Compile-time validations
val name2: Name = Name("") // COMPILATION ERROR! did not satisfy hasLength(notEqualTo(0))
val email2: Email = Email("whatever") // COMPILATION ERROR! did not satisfy matches(^([w-.])*@([w-])*(.)*([w-]){2,4}$)
val address2: Address = Address("") // COMPILATION ERROR! did not satisfy hasLength(notEqualTo(0))
val person2: Person = Person(name2, email2, address2)
138. Compile-time validations
val name2: Name = Name("") // COMPILATION ERROR! did not satisfy hasLength(notEqualTo(0))
val email2: Email = Email("whatever") // COMPILATION ERROR! did not satisfy matches(^([w-.])*@([w-])*(.)*([w-]){2,4}$)
val address2: Address = Address("") // COMPILATION ERROR! did not satisfy hasLength(notEqualTo(0))
val person2: Person = Person(name2, email2, address2)
139. Compile-time validations
val name2: Name = Name("") // COMPILATION ERROR! did not satisfy hasLength(notEqualTo(0))
val email2: Email = Email("whatever") // COMPILATION ERROR! did not satisfy matches(^([w-.])*@([w-])*(.)*([w-]){2,4}$)
val address2: Address = Address("") // COMPILATION ERROR! did not satisfy hasLength(notEqualTo(0))
val person2: Person = Person(name2, email2, address2)
140. Compile-time validations
val name2: Name = Name("") // COMPILATION ERROR! did not satisfy hasLength(notEqualTo(0))
val email2: Email = Email("whatever") // COMPILATION ERROR! did not satisfy matches(^([w-.])*@([w-])*(.)*([w-]){2,4}$)
val address2: Address = Address("") // COMPILATION ERROR! did not satisfy hasLength(notEqualTo(0))
val person2: Person = Person(name2, email2, address2)
144. Runtime validations
val name3: Validation[String, Name] = Name.make(scala.io.StdIn.readLine())
val email3: Validation[String, Email] = Email.make(scala.io.StdIn.readLine())
val address3: Validation[String, Address] = Address.make(scala.io.StdIn.readLine())
// Short-circuiting
val person3a: Validation[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
// Non short-circuiting
val person3b: Validation[String, Person] = Validation.validateWith(name3, email3, address3)(Person.apply)
145. Runtime validations
val name3: Validation[String, Name] = Name.make(scala.io.StdIn.readLine())
val email3: Validation[String, Email] = Email.make(scala.io.StdIn.readLine())
val address3: Validation[String, Address] = Address.make(scala.io.StdIn.readLine())
// Short-circuiting
val person3a: Validation[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
// Non short-circuiting
val person3b: Validation[String, Person] = Validation.validateWith(name3, email3, address3)(Person.apply)
146. Runtime validations
val name3: Validation[String, Name] = Name.make(scala.io.StdIn.readLine())
val email3: Validation[String, Email] = Email.make(scala.io.StdIn.readLine())
val address3: Validation[String, Address] = Address.make(scala.io.StdIn.readLine())
// Short-circuiting
val person3a: Validation[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
// Non short-circuiting
val person3b: Validation[String, Person] = Validation.validateWith(name3, email3, address3)(Person.apply)
147. Runtime validations
val name3: Validation[String, Name] = Name.make(scala.io.StdIn.readLine())
val email3: Validation[String, Email] = Email.make(scala.io.StdIn.readLine())
val address3: Validation[String, Address] = Address.make(scala.io.StdIn.readLine())
// Short-circuiting
val person3a: Validation[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
// Non short-circuiting
val person3b: Validation[String, Person] = Validation.validateWith(name3, email3, address3)(Person.apply)
148. Runtime validations
val name3: Validation[String, Name] = Name.make(scala.io.StdIn.readLine())
val email3: Validation[String, Email] = Email.make(scala.io.StdIn.readLine())
val address3: Validation[String, Address] = Address.make(scala.io.StdIn.readLine())
// Short-circuiting
val person3a: Validation[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
// Non short-circuiting
val person3b: Validation[String, Person] = Validation.validateWith(name3, email3, address3)(Person.apply)
149. Runtime validations
val name3: Validation[String, Name] = Name.make(scala.io.StdIn.readLine())
val email3: Validation[String, Email] = Email.make(scala.io.StdIn.readLine())
val address3: Validation[String, Address] = Address.make(scala.io.StdIn.readLine())
// Short-circuiting
val person3a: Validation[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
// Non short-circuiting
val person3b: Validation[String, Person] = Validation.validateWith(name3, email3, address3)(Person.apply)
150. Using Newtypes
// We can define methods that work with Email
def getUser(email: Email): String = Email.unwrap(email).split("@").head
val myEmail = Email("jorge.vasquez@scalac.io")
getUser(myEmail) // jorge.vasquez
151. Using Newtypes
// We can define methods that work with Email
def getUser(email: Email): String = Email.unwrap(email).split("@").head
val myEmail = Email("jorge.vasquez@scalac.io")
getUser(myEmail) // jorge.vasquez
152. Using Newtypes
// We can define methods that work with Email
def getUser(email: Email): String = Email.unwrap(email).split("@").head
val myEmail = Email("jorge.vasquez@scalac.io")
getUser(myEmail) // jorge.vasquez
153. Using Newtypes
// We can define methods that work with Email
def getUser(email: Email): String = Email.unwrap(email).split("@").head
val myEmail = Email("jorge.vasquez@scalac.io")
getUser(myEmail) // jorge.vasquez
172. Summary
• We need more precise data modelling for our
applications
• There are several options, each one with its own
limitations
173. Summary
• We need more precise data modelling for our
applications
• There are several options, each one with its own
limitations
• ZIO Prelude Smart Types provides a solution to those
limitations