SlideShare uma empresa Scribd logo
1 de 83
Baixar para ler offline
Coming soon to
ZIO Prelude
ZIO World 2021
March 11
Jorge Vásquez
Scala Developer
@Scalac
Background
ZIO Prelude is a Scala-first take on functional abstractions
Background
ZIO Prelude is a Scala-first take on functional abstractions
• Type classes to eliminate duplication / boilerplate
Background
ZIO Prelude is a Scala-first take on functional abstractions
• Type classes to eliminate duplication / boilerplate
• Data types that complement the Scala standard library
(NonEmptyList, ZPure)
Background
ZIO Prelude is a Scala-first take on functional abstractions
• Type classes to eliminate duplication / boilerplate
• Data types that complement the Scala standard library
(NonEmptyList, ZPure)
• Newtypes / subtypes
Problem
Precise Data
Modelling
Representing
everything with
Simple Types
final case class Person(
name: String,
email: String,
address: String
)
Representing
everything with
Simple Types
final case class Person(
name: String,
email: String,
address: String
)
Representing
everything with
Simple Types
final case class Person(
name: String,
email: String,
address: String
)
Representing
everything with
Simple Types
final case class Person(
name: String,
email: String,
address: String
)
Representing
everything with
Simple Types
final case class Person(
name: String,
email: String,
address: String
)
Storing invalid data
in databases
name email address
t1@tst.co whatever
Main Av. t2@tst.co
Applications throwing exceptions
Smart Constructors
final case class Name private(value: String)
object Name:
def make(value: String): Either[String, Name] = ???
final case class Email private(value: String)
object Email:
def make(value: String): Either[String, Email] = ???
final case class Address private(value: String)
object Address:
def make(value: String): Either[String, Address] = ???
final case class Person(
name: Name,
email: Email,
address: Address
)
Smart Constructors
final case class Name private(value: String)
object Name:
def make(value: String): Either[String, Name] = ???
final case class Email private(value: String)
object Email:
def make(value: String): Either[String, Email] = ???
final case class Address private(value: String)
object Address:
def make(value: String): Either[String, Address] = ???
final case class Person(
name: Name,
email: Email,
address: Address
)
Smart Constructors
final case class Name private(value: String)
object Name:
def make(value: String): Either[String, Name] = ???
final case class Email private(value: String)
object Email:
def make(value: String): Either[String, Email] = ???
final case class Address private(value: String)
object Address:
def make(value: String): Either[String, Address] = ???
final case class Person(
name: Name,
email: Email,
address: Address
)
Smart Constructors
final case class Name private(value: String)
object Name:
def make(value: String): Either[String, Name] = ???
final case class Email private(value: String)
object Email:
def make(value: String): Either[String, Email] = ???
final case class Address private(value: String)
object Address:
def make(value: String): Either[String, Address] = ???
final case class Person(
name: Name,
email: Email,
address: Address
)
Smart Constructors
final case class Name private(value: String)
object Name:
def make(value: String): Either[String, Name] = ???
final case class Email private(value: String)
object Email:
def make(value: String): Either[String, Email] = ???
final case class Address private(value: String)
object Address:
def make(value: String): Either[String, Address] = ???
final case class Person(
name: Name,
email: Email,
address: Address
)
Smart Constructors
val person1: 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)
val person2: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
Smart Constructors
val person1: 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)
val person2: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
Smart Constructors
val person1: 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)
val person2: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
Smart Constructors
val person1: 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)
val person2: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
Smart Constructors
val person1: 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)
val person2: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
Smart Constructors
val person1: 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)
val person2: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
Smart Constructors
val person1: 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)
val person2: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
Smart Constructors
val person1: 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)
val person2: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
Smart Constructors
val person1: 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)
val person2: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
Smart Constructors
val person1: 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)
val person2: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
Smart Constructors
val person1: 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)
val person2: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
Opaque types +
Smart Constructors
opaque type Name = String
object Name:
def make(value: String): Either[String, Name] = ???
opaque type Email = String
object Email:
def make(value: String): Either[String, Email] = ???
opaque type Address = String
object Address:
def make(value: String): Either[String, Address] = ???
final case class Person(
name: Name,
email: Email,
address: Address
)
Opaque types +
Smart Constructors
opaque type Name = String
object Name:
def make(value: String): Either[String, Name] = ???
opaque type Email = String
object Email:
def make(value: String): Either[String, Email] = ???
opaque type Address = String
object Address:
def make(value: String): Either[String, Address] = ???
final case class Person(
name: Name,
email: Email,
address: Address
)
Opaque types +
Smart Constructors
opaque type Name = String
object Name:
def make(value: String): Either[String, Name] = ???
opaque type Email = String
object Email:
def make(value: String): Either[String, Email] = ???
opaque type Address = String
object Address:
def make(value: String): Either[String, Address] = ???
final case class Person(
name: Name,
email: Email,
address: Address
)
Opaque types +
Smart Constructors
opaque type Name = String
object Name:
def make(value: String): Either[String, Name] = ???
opaque type Email = String
object Email:
def make(value: String): Either[String, Email] = ???
opaque type Address = String
object Address:
def make(value: String): Either[String, Address] = ???
final case class Person(
name: Name,
email: Email,
address: Address
)
Opaque types +
Smart Constructors
opaque type Name = String
object Name:
def make(value: String): Either[String, Name] = ???
opaque type Email = String
object Email:
def make(value: String): Either[String, Email] = ???
opaque type Address = String
object Address:
def make(value: String): Either[String, Address] = ???
final case class Person(
name: Name,
email: Email,
address: Address
)
Opaque types +
Smart Constructors
val person1: 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)
val person2: Either[String, Person] =
for {
name <- Name.make("")
email <- Email.make("whatever")
address <- Address.make("")
} yield Person(name, email, address)
Wouldn't it be dreamy if we
could have more precise data
modelling, without unnecessary
overhead?
Enter
ZIO Prelude
Refinement Types
Powered by
Scala 3 Macros
Refinement Types
import Assertion._
import Assertion.Regex._
type Name <: String
inline def Name: String Refined Name = Refined {
notEmpty
}
Refinement Types
import Assertion._
import Assertion.Regex._
type Name <: String
inline def Name: String Refined Name = Refined {
notEmpty
}
Refinement Types
import Assertion._
import Assertion.Regex._
type Email <: String
inline def Email: String Refined Email = Refined {
matches {
char(isAlpha || isDigit).min(1)
~ char(equal('@'))
~ char(isAlpha || isDigit).min(1)
~ char(equal('.'))
~ char(isAlpha).min(1)
}
}
Refinement Types
import Assertion._
import Assertion.Regex._
type Email <: String
inline def Email: String Refined Email = Refined {
matches {
char(isAlpha || isDigit).min(1)
~ char(equal('@'))
~ char(isAlpha || isDigit).min(1)
~ char(equal('.'))
~ char(isAlpha).min(1)
}
}
Refinement Types
import Assertion._
import Assertion.Regex._
type Address <: String
inline def Address: String Refined Address = Refined {
notEmpty
}
Refinement Types
import Assertion._
import Assertion.Regex._
type Address <: String
inline def Address: String Refined Address = Refined {
notEmpty
}
Smarter 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)
Smarter 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)
Smarter 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)
Smarter 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)
Smarter 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)
Smarter constructors!
val name2: Name = Name("") // COMPILATION ERROR! must not be empty
val email2: Email = Email("whatever") // COMPILATION ERROR! must match regex
val address2: Address = Address("") // COMPILATION ERROR! must not be empty
val person2: Person = Person(name2, email2, address2)
Smarter constructors!
val name2: Name = Name("") // COMPILATION ERROR! must not be empty
val email2: Email = Email("whatever") // COMPILATION ERROR! must match regex
val address2: Address = Address("") // COMPILATION ERROR! must not be empty
val person2: Person = Person(name2, email2, address2)
Smarter constructors!
val name2: Name = Name("") // COMPILATION ERROR! must not be empty
val email2: Email = Email("whatever") // COMPILATION ERROR! must match regex
val address2: Address = Address("") // COMPILATION ERROR! must not be empty
val person2: Person = Person(name2, email2, address2)
Smarter constructors!
val name2: Name = Name("") // COMPILATION ERROR! must not be empty
val email2: Email = Email("whatever") // COMPILATION ERROR! must match regex
val address2: Address = Address("") // COMPILATION ERROR! must not be empty
val person2: Person = Person(name2, email2, address2)
Smarter constructors!
val name2: Name = Name("") // COMPILATION ERROR! must not be empty
val email2: Email = Email("whatever") // COMPILATION ERROR! must match regex
val address2: Address = Address("") // COMPILATION ERROR! must not be empty
val person2: Person = Person(name2, email2, address2)
Smarter constructors!
val name3: Either[String, Name] = Name(scala.io.StdIn.readLine())
val email3: Either[String, Email] = Email(scala.io.StdIn.readLine())
val address3: Either[String, Address] = Address(scala.io.StdIn.readLine())
val person3: Either[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
Smarter constructors!
val name3: Either[String, Name] = Name(scala.io.StdIn.readLine())
val email3: Either[String, Email] = Email(scala.io.StdIn.readLine())
val address3: Either[String, Address] = Address(scala.io.StdIn.readLine())
val person3: Either[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
Smarter constructors!
val name3: Either[String, Name] = Name(scala.io.StdIn.readLine())
val email3: Either[String, Email] = Email(scala.io.StdIn.readLine())
val address3: Either[String, Address] = Address(scala.io.StdIn.readLine())
val person3: Either[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
Smarter constructors!
val name3: Either[String, Name] = Name(scala.io.StdIn.readLine())
val email3: Either[String, Email] = Email(scala.io.StdIn.readLine())
val address3: Either[String, Address] = Address(scala.io.StdIn.readLine())
val person3: Either[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
Smarter constructors!
val name3: Either[String, Name] = Name(scala.io.StdIn.readLine())
val email3: Either[String, Email] = Email(scala.io.StdIn.readLine())
val address3: Either[String, Address] = Address(scala.io.StdIn.readLine())
val person3: Either[String, Person] =
for {
name <- name3
email <- email3
address <- address3
} yield Person(name, email, address)
No wrapping/unwrapping!
type Natural <: Int
inline def Natural: Int Refined Natural = Refined {
greaterThanEqual(0)
}
type Age <: Int
inline def Age: Int Refined Age = Refined {
greaterThanEqual(0) && lessThanEqual(150)
}
val natural: Natural = Natural(5)
val age: Age = Age(60)
def add(a: Int, b: Int): Int = a + b
add(natural, age)
// 65
No wrapping/unwrapping!
type Natural <: Int
inline def Natural: Int Refined Natural = Refined {
greaterThanEqual(0)
}
type Age <: Int
inline def Age: Int Refined Age = Refined {
greaterThanEqual(0) && lessThanEqual(150)
}
val natural: Natural = Natural(5)
val age: Age = Age(60)
def add(a: Int, b: Int): Int = a + b
add(natural, age)
// 65
No wrapping/unwrapping!
type Natural <: Int
inline def Natural: Int Refined Natural = Refined {
greaterThanEqual(0)
}
type Age <: Int
inline def Age: Int Refined Age = Refined {
greaterThanEqual(0) && lessThanEqual(150)
}
val natural: Natural = Natural(5)
val age: Age = Age(60)
def add(a: Int, b: Int): Int = a + b
add(natural, age)
// 65
No wrapping/unwrapping!
type Natural <: Int
inline def Natural: Int Refined Natural = Refined {
greaterThanEqual(0)
}
type Age <: Int
inline def Age: Int Refined Age = Refined {
greaterThanEqual(0) && lessThanEqual(150)
}
val natural: Natural = Natural(5)
val age: Age = Age(60)
def add(a: Int, b: Int): Int = a + b
add(natural, age)
// 65
No wrapping/unwrapping!
type Natural <: Int
inline def Natural: Int Refined Natural = Refined {
greaterThanEqual(0)
}
type Age <: Int
inline def Age: Int Refined Age = Refined {
greaterThanEqual(0) && lessThanEqual(150)
}
val natural: Natural = Natural(5)
val age: Age = Age(60)
def add(a: Int, b: Int): Int = a + b
add(natural, age)
// 65
No wrapping/unwrapping!
type Natural <: Int
inline def Natural: Int Refined Natural = Refined {
greaterThanEqual(0)
}
type Age <: Int
inline def Age: Int Refined Age = Refined {
greaterThanEqual(0) && lessThanEqual(150)
}
val natural: Natural = Natural(5)
val age: Age = Age(60)
def add(a: Int, b: Int): Int = a + b
add(natural, age)
// 65
No wrapping/unwrapping!
type Natural <: Int
inline def Natural: Int Refined Natural = Refined {
greaterThanEqual(0)
}
type Age <: Int
inline def Age: Int Refined Age = Refined {
greaterThanEqual(0) && lessThanEqual(150)
}
val natural: Natural = Natural(5)
val age: Age = Age(60)
def add(a: Int, b: Int): Int = a + b
add(natural, age)
// 65
No wrapping/unwrapping!
type Natural <: Int
inline def Natural: Int Refined Natural = Refined {
greaterThanEqual(0)
}
type Age <: Int
inline def Age: Int Refined Age = Refined {
greaterThanEqual(0) && lessThanEqual(150)
}
val natural: Natural = Natural(5)
val age: Age = Age(60)
def add(a: Int, b: Int): Int = a + b
add(natural, age)
// 65
Summary
Summary
Summary
• We need more precise data modelling for our
applications
Summary
• We need more precise data modelling for our
applications
• We can use case classes with smart constructors. This
imposes additional runtime overhead
Summary
• We need more precise data modelling for our
applications
• We can use case classes with smart constructors. This
imposes additional runtime overhead
• Using opaque types removes some of the overhead, but
not all of it
Summary
ZIO Prelude Refinement Types will provide a solution to these
problems:
Summary
ZIO Prelude Refinement Types will provide a solution to these
problems:
• Smarter Constructors with Composable Assertions that work at
compile time AND at run time
Summary
ZIO Prelude Refinement Types will provide a solution to these
problems:
• Smarter Constructors with Composable Assertions that work at
compile time AND at run time
• No additional overhead because of wrapping/unwrapping
Summary
ZIO Prelude Refinement Types will provide a solution to these
problems:
• Smarter Constructors with Composable Assertions that work at
compile time AND at run time
• No additional overhead because of wrapping/unwrapping
• All of this thanks to the power of Scala 3 Macros!. No weird stuff,
just standard Scala
Contact me
@jorvasquez2301
jorge-vasquez-2301
jorge.vasquez@scalac.io

Mais conteúdo relacionado

Mais procurados

Mais procurados (17)

Spsl v unit - final
Spsl v unit - finalSpsl v unit - final
Spsl v unit - final
 
Joy of scala
Joy of scalaJoy of scala
Joy of scala
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
Java string handling
Java string handlingJava string handling
Java string handling
 
ハイブリッド言語Scalaを使う
ハイブリッド言語Scalaを使うハイブリッド言語Scalaを使う
ハイブリッド言語Scalaを使う
 
Python: Basic Inheritance
Python: Basic InheritancePython: Basic Inheritance
Python: Basic Inheritance
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
 
Getting Started With Scala
Getting Started With ScalaGetting Started With Scala
Getting Started With Scala
 
Scala for curious
Scala for curiousScala for curious
Scala for curious
 
Dictionary in python
Dictionary in pythonDictionary in python
Dictionary in python
 
Scala: Functioneel programmeren in een object georiënteerde wereld
Scala: Functioneel programmeren in een object georiënteerde wereldScala: Functioneel programmeren in een object georiënteerde wereld
Scala: Functioneel programmeren in een object georiënteerde wereld
 
Scala collections
Scala collectionsScala collections
Scala collections
 
The Ring programming language version 1.6 book - Part 33 of 189
The Ring programming language version 1.6 book - Part 33 of 189The Ring programming language version 1.6 book - Part 33 of 189
The Ring programming language version 1.6 book - Part 33 of 189
 
Scala - en bedre Java?
Scala - en bedre Java?Scala - en bedre Java?
Scala - en bedre Java?
 
Scala jargon cheatsheet
Scala jargon cheatsheetScala jargon cheatsheet
Scala jargon cheatsheet
 
Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlin
 
Demystifying functional programming with Scala
Demystifying functional programming with ScalaDemystifying functional programming with Scala
Demystifying functional programming with Scala
 

Semelhante a ZIO Prelude - ZIO World 2021

pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
Tomasz Wrobel
 

Semelhante a ZIO Prelude - ZIO World 2021 (20)

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!
 
First few months with Kotlin - Introduction through android examples
First few months with Kotlin - Introduction through android examplesFirst few months with Kotlin - Introduction through android examples
First few months with Kotlin - Introduction through android examples
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Basics of Python programming (part 2)
Basics of Python programming (part 2)Basics of Python programming (part 2)
Basics of Python programming (part 2)
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
Crystal presentation in NY
Crystal presentation in NYCrystal presentation in NY
Crystal presentation in NY
 
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
 
Beginner's Python Cheat Sheet.pdf
Beginner's Python Cheat Sheet.pdfBeginner's Python Cheat Sheet.pdf
Beginner's Python Cheat Sheet.pdf
 
beginners_python_cheat_sheet_pcc_all (3).pptx
beginners_python_cheat_sheet_pcc_all (3).pptxbeginners_python_cheat_sheet_pcc_all (3).pptx
beginners_python_cheat_sheet_pcc_all (3).pptx
 
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
 
Python Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayPython Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard Way
 
Scala in a Java 8 World
Scala in a Java 8 WorldScala in a Java 8 World
Scala in a Java 8 World
 
Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge
 
1. python
1. python1. python
1. python
 
Python cheatsheet for beginners
Python cheatsheet for beginnersPython cheatsheet for beginners
Python cheatsheet for beginners
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
 

Mais de Jorge Vásquez

Mais de Jorge Vásquez (6)

Behold! The Happy Path To Captivate Your Users With Stunning CLI Apps!
Behold! The Happy Path To Captivate Your Users With Stunning CLI Apps!Behold! The Happy Path To Captivate Your Users With Stunning CLI Apps!
Behold! The Happy Path To Captivate Your Users With Stunning CLI Apps!
 
Programación Funcional 101 con Scala y ZIO 2.0
Programación Funcional 101 con Scala y ZIO 2.0Programación Funcional 101 con Scala y ZIO 2.0
Programación Funcional 101 con Scala y ZIO 2.0
 
Consiguiendo superpoderes para construir aplicaciones modernas en la JVM con ZIO
Consiguiendo superpoderes para construir aplicaciones modernas en la JVM con ZIOConsiguiendo superpoderes para construir aplicaciones modernas en la JVM con ZIO
Consiguiendo superpoderes para construir aplicaciones modernas en la JVM con ZIO
 
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
 
The Terror-Free Guide to Introducing Functional Scala at Work
The Terror-Free Guide to Introducing Functional Scala at WorkThe Terror-Free Guide to Introducing Functional Scala at Work
The Terror-Free Guide to Introducing Functional Scala at Work
 
Introduction to programming with ZIO functional effects
Introduction to programming with ZIO functional effectsIntroduction to programming with ZIO functional effects
Introduction to programming with ZIO functional effects
 

Último

Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
masabamasaba
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
chiefasafspells
 

Último (20)

Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 

ZIO Prelude - ZIO World 2021

  • 1. Coming soon to ZIO Prelude ZIO World 2021 March 11
  • 3. Background ZIO Prelude is a Scala-first take on functional abstractions
  • 4. Background ZIO Prelude is a Scala-first take on functional abstractions • Type classes to eliminate duplication / boilerplate
  • 5. Background ZIO Prelude is a Scala-first take on functional abstractions • Type classes to eliminate duplication / boilerplate • Data types that complement the Scala standard library (NonEmptyList, ZPure)
  • 6. Background ZIO Prelude is a Scala-first take on functional abstractions • Type classes to eliminate duplication / boilerplate • Data types that complement the Scala standard library (NonEmptyList, ZPure) • Newtypes / subtypes
  • 8. Representing everything with Simple Types final case class Person( name: String, email: String, address: String )
  • 9. Representing everything with Simple Types final case class Person( name: String, email: String, address: String )
  • 10. Representing everything with Simple Types final case class Person( name: String, email: String, address: String )
  • 11. Representing everything with Simple Types final case class Person( name: String, email: String, address: String )
  • 12. Representing everything with Simple Types final case class Person( name: String, email: String, address: String )
  • 13. Storing invalid data in databases name email address t1@tst.co whatever Main Av. t2@tst.co
  • 15.
  • 16. Smart Constructors final case class Name private(value: String) object Name: def make(value: String): Either[String, Name] = ??? final case class Email private(value: String) object Email: def make(value: String): Either[String, Email] = ??? final case class Address private(value: String) object Address: def make(value: String): Either[String, Address] = ??? final case class Person( name: Name, email: Email, address: Address )
  • 17. Smart Constructors final case class Name private(value: String) object Name: def make(value: String): Either[String, Name] = ??? final case class Email private(value: String) object Email: def make(value: String): Either[String, Email] = ??? final case class Address private(value: String) object Address: def make(value: String): Either[String, Address] = ??? final case class Person( name: Name, email: Email, address: Address )
  • 18. Smart Constructors final case class Name private(value: String) object Name: def make(value: String): Either[String, Name] = ??? final case class Email private(value: String) object Email: def make(value: String): Either[String, Email] = ??? final case class Address private(value: String) object Address: def make(value: String): Either[String, Address] = ??? final case class Person( name: Name, email: Email, address: Address )
  • 19. Smart Constructors final case class Name private(value: String) object Name: def make(value: String): Either[String, Name] = ??? final case class Email private(value: String) object Email: def make(value: String): Either[String, Email] = ??? final case class Address private(value: String) object Address: def make(value: String): Either[String, Address] = ??? final case class Person( name: Name, email: Email, address: Address )
  • 20. Smart Constructors final case class Name private(value: String) object Name: def make(value: String): Either[String, Name] = ??? final case class Email private(value: String) object Email: def make(value: String): Either[String, Email] = ??? final case class Address private(value: String) object Address: def make(value: String): Either[String, Address] = ??? final case class Person( name: Name, email: Email, address: Address )
  • 21.
  • 22.
  • 23. Smart Constructors val person1: 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) val person2: Either[String, Person] = for { name <- Name.make("") email <- Email.make("whatever") address <- Address.make("") } yield Person(name, email, address)
  • 24. Smart Constructors val person1: 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) val person2: Either[String, Person] = for { name <- Name.make("") email <- Email.make("whatever") address <- Address.make("") } yield Person(name, email, address)
  • 25. Smart Constructors val person1: 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) val person2: Either[String, Person] = for { name <- Name.make("") email <- Email.make("whatever") address <- Address.make("") } yield Person(name, email, address)
  • 26. Smart Constructors val person1: 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) val person2: Either[String, Person] = for { name <- Name.make("") email <- Email.make("whatever") address <- Address.make("") } yield Person(name, email, address)
  • 27. Smart Constructors val person1: 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) val person2: Either[String, Person] = for { name <- Name.make("") email <- Email.make("whatever") address <- Address.make("") } yield Person(name, email, address)
  • 28. Smart Constructors val person1: 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) val person2: Either[String, Person] = for { name <- Name.make("") email <- Email.make("whatever") address <- Address.make("") } yield Person(name, email, address)
  • 29. Smart Constructors val person1: 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) val person2: Either[String, Person] = for { name <- Name.make("") email <- Email.make("whatever") address <- Address.make("") } yield Person(name, email, address)
  • 30. Smart Constructors val person1: 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) val person2: Either[String, Person] = for { name <- Name.make("") email <- Email.make("whatever") address <- Address.make("") } yield Person(name, email, address)
  • 31. Smart Constructors val person1: 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) val person2: Either[String, Person] = for { name <- Name.make("") email <- Email.make("whatever") address <- Address.make("") } yield Person(name, email, address)
  • 32. Smart Constructors val person1: 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) val person2: Either[String, Person] = for { name <- Name.make("") email <- Email.make("whatever") address <- Address.make("") } yield Person(name, email, address)
  • 33. Smart Constructors val person1: 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) val person2: Either[String, Person] = for { name <- Name.make("") email <- Email.make("whatever") address <- Address.make("") } yield Person(name, email, address)
  • 34. Opaque types + Smart Constructors opaque type Name = String object Name: def make(value: String): Either[String, Name] = ??? opaque type Email = String object Email: def make(value: String): Either[String, Email] = ??? opaque type Address = String object Address: def make(value: String): Either[String, Address] = ??? final case class Person( name: Name, email: Email, address: Address )
  • 35. Opaque types + Smart Constructors opaque type Name = String object Name: def make(value: String): Either[String, Name] = ??? opaque type Email = String object Email: def make(value: String): Either[String, Email] = ??? opaque type Address = String object Address: def make(value: String): Either[String, Address] = ??? final case class Person( name: Name, email: Email, address: Address )
  • 36. Opaque types + Smart Constructors opaque type Name = String object Name: def make(value: String): Either[String, Name] = ??? opaque type Email = String object Email: def make(value: String): Either[String, Email] = ??? opaque type Address = String object Address: def make(value: String): Either[String, Address] = ??? final case class Person( name: Name, email: Email, address: Address )
  • 37. Opaque types + Smart Constructors opaque type Name = String object Name: def make(value: String): Either[String, Name] = ??? opaque type Email = String object Email: def make(value: String): Either[String, Email] = ??? opaque type Address = String object Address: def make(value: String): Either[String, Address] = ??? final case class Person( name: Name, email: Email, address: Address )
  • 38. Opaque types + Smart Constructors opaque type Name = String object Name: def make(value: String): Either[String, Name] = ??? opaque type Email = String object Email: def make(value: String): Either[String, Email] = ??? opaque type Address = String object Address: def make(value: String): Either[String, Address] = ??? final case class Person( name: Name, email: Email, address: Address )
  • 39.
  • 40. Opaque types + Smart Constructors val person1: 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) val person2: Either[String, Person] = for { name <- Name.make("") email <- Email.make("whatever") address <- Address.make("") } yield Person(name, email, address)
  • 41.
  • 42.
  • 43. Wouldn't it be dreamy if we could have more precise data modelling, without unnecessary overhead?
  • 45. Refinement Types import Assertion._ import Assertion.Regex._ type Name <: String inline def Name: String Refined Name = Refined { notEmpty }
  • 46. Refinement Types import Assertion._ import Assertion.Regex._ type Name <: String inline def Name: String Refined Name = Refined { notEmpty }
  • 47. Refinement Types import Assertion._ import Assertion.Regex._ type Email <: String inline def Email: String Refined Email = Refined { matches { char(isAlpha || isDigit).min(1) ~ char(equal('@')) ~ char(isAlpha || isDigit).min(1) ~ char(equal('.')) ~ char(isAlpha).min(1) } }
  • 48. Refinement Types import Assertion._ import Assertion.Regex._ type Email <: String inline def Email: String Refined Email = Refined { matches { char(isAlpha || isDigit).min(1) ~ char(equal('@')) ~ char(isAlpha || isDigit).min(1) ~ char(equal('.')) ~ char(isAlpha).min(1) } }
  • 49. Refinement Types import Assertion._ import Assertion.Regex._ type Address <: String inline def Address: String Refined Address = Refined { notEmpty }
  • 50. Refinement Types import Assertion._ import Assertion.Regex._ type Address <: String inline def Address: String Refined Address = Refined { notEmpty }
  • 51. Smarter 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)
  • 52. Smarter 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)
  • 53. Smarter 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)
  • 54. Smarter 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)
  • 55. Smarter 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)
  • 56. Smarter constructors! val name2: Name = Name("") // COMPILATION ERROR! must not be empty val email2: Email = Email("whatever") // COMPILATION ERROR! must match regex val address2: Address = Address("") // COMPILATION ERROR! must not be empty val person2: Person = Person(name2, email2, address2)
  • 57. Smarter constructors! val name2: Name = Name("") // COMPILATION ERROR! must not be empty val email2: Email = Email("whatever") // COMPILATION ERROR! must match regex val address2: Address = Address("") // COMPILATION ERROR! must not be empty val person2: Person = Person(name2, email2, address2)
  • 58. Smarter constructors! val name2: Name = Name("") // COMPILATION ERROR! must not be empty val email2: Email = Email("whatever") // COMPILATION ERROR! must match regex val address2: Address = Address("") // COMPILATION ERROR! must not be empty val person2: Person = Person(name2, email2, address2)
  • 59. Smarter constructors! val name2: Name = Name("") // COMPILATION ERROR! must not be empty val email2: Email = Email("whatever") // COMPILATION ERROR! must match regex val address2: Address = Address("") // COMPILATION ERROR! must not be empty val person2: Person = Person(name2, email2, address2)
  • 60. Smarter constructors! val name2: Name = Name("") // COMPILATION ERROR! must not be empty val email2: Email = Email("whatever") // COMPILATION ERROR! must match regex val address2: Address = Address("") // COMPILATION ERROR! must not be empty val person2: Person = Person(name2, email2, address2)
  • 61. Smarter constructors! val name3: Either[String, Name] = Name(scala.io.StdIn.readLine()) val email3: Either[String, Email] = Email(scala.io.StdIn.readLine()) val address3: Either[String, Address] = Address(scala.io.StdIn.readLine()) val person3: Either[String, Person] = for { name <- name3 email <- email3 address <- address3 } yield Person(name, email, address)
  • 62. Smarter constructors! val name3: Either[String, Name] = Name(scala.io.StdIn.readLine()) val email3: Either[String, Email] = Email(scala.io.StdIn.readLine()) val address3: Either[String, Address] = Address(scala.io.StdIn.readLine()) val person3: Either[String, Person] = for { name <- name3 email <- email3 address <- address3 } yield Person(name, email, address)
  • 63. Smarter constructors! val name3: Either[String, Name] = Name(scala.io.StdIn.readLine()) val email3: Either[String, Email] = Email(scala.io.StdIn.readLine()) val address3: Either[String, Address] = Address(scala.io.StdIn.readLine()) val person3: Either[String, Person] = for { name <- name3 email <- email3 address <- address3 } yield Person(name, email, address)
  • 64. Smarter constructors! val name3: Either[String, Name] = Name(scala.io.StdIn.readLine()) val email3: Either[String, Email] = Email(scala.io.StdIn.readLine()) val address3: Either[String, Address] = Address(scala.io.StdIn.readLine()) val person3: Either[String, Person] = for { name <- name3 email <- email3 address <- address3 } yield Person(name, email, address)
  • 65. Smarter constructors! val name3: Either[String, Name] = Name(scala.io.StdIn.readLine()) val email3: Either[String, Email] = Email(scala.io.StdIn.readLine()) val address3: Either[String, Address] = Address(scala.io.StdIn.readLine()) val person3: Either[String, Person] = for { name <- name3 email <- email3 address <- address3 } yield Person(name, email, address)
  • 66. No wrapping/unwrapping! type Natural <: Int inline def Natural: Int Refined Natural = Refined { greaterThanEqual(0) } type Age <: Int inline def Age: Int Refined Age = Refined { greaterThanEqual(0) && lessThanEqual(150) } val natural: Natural = Natural(5) val age: Age = Age(60) def add(a: Int, b: Int): Int = a + b add(natural, age) // 65
  • 67. No wrapping/unwrapping! type Natural <: Int inline def Natural: Int Refined Natural = Refined { greaterThanEqual(0) } type Age <: Int inline def Age: Int Refined Age = Refined { greaterThanEqual(0) && lessThanEqual(150) } val natural: Natural = Natural(5) val age: Age = Age(60) def add(a: Int, b: Int): Int = a + b add(natural, age) // 65
  • 68. No wrapping/unwrapping! type Natural <: Int inline def Natural: Int Refined Natural = Refined { greaterThanEqual(0) } type Age <: Int inline def Age: Int Refined Age = Refined { greaterThanEqual(0) && lessThanEqual(150) } val natural: Natural = Natural(5) val age: Age = Age(60) def add(a: Int, b: Int): Int = a + b add(natural, age) // 65
  • 69. No wrapping/unwrapping! type Natural <: Int inline def Natural: Int Refined Natural = Refined { greaterThanEqual(0) } type Age <: Int inline def Age: Int Refined Age = Refined { greaterThanEqual(0) && lessThanEqual(150) } val natural: Natural = Natural(5) val age: Age = Age(60) def add(a: Int, b: Int): Int = a + b add(natural, age) // 65
  • 70. No wrapping/unwrapping! type Natural <: Int inline def Natural: Int Refined Natural = Refined { greaterThanEqual(0) } type Age <: Int inline def Age: Int Refined Age = Refined { greaterThanEqual(0) && lessThanEqual(150) } val natural: Natural = Natural(5) val age: Age = Age(60) def add(a: Int, b: Int): Int = a + b add(natural, age) // 65
  • 71. No wrapping/unwrapping! type Natural <: Int inline def Natural: Int Refined Natural = Refined { greaterThanEqual(0) } type Age <: Int inline def Age: Int Refined Age = Refined { greaterThanEqual(0) && lessThanEqual(150) } val natural: Natural = Natural(5) val age: Age = Age(60) def add(a: Int, b: Int): Int = a + b add(natural, age) // 65
  • 72. No wrapping/unwrapping! type Natural <: Int inline def Natural: Int Refined Natural = Refined { greaterThanEqual(0) } type Age <: Int inline def Age: Int Refined Age = Refined { greaterThanEqual(0) && lessThanEqual(150) } val natural: Natural = Natural(5) val age: Age = Age(60) def add(a: Int, b: Int): Int = a + b add(natural, age) // 65
  • 73. No wrapping/unwrapping! type Natural <: Int inline def Natural: Int Refined Natural = Refined { greaterThanEqual(0) } type Age <: Int inline def Age: Int Refined Age = Refined { greaterThanEqual(0) && lessThanEqual(150) } val natural: Natural = Natural(5) val age: Age = Age(60) def add(a: Int, b: Int): Int = a + b add(natural, age) // 65
  • 76. Summary • We need more precise data modelling for our applications
  • 77. Summary • We need more precise data modelling for our applications • We can use case classes with smart constructors. This imposes additional runtime overhead
  • 78. Summary • We need more precise data modelling for our applications • We can use case classes with smart constructors. This imposes additional runtime overhead • Using opaque types removes some of the overhead, but not all of it
  • 79. Summary ZIO Prelude Refinement Types will provide a solution to these problems:
  • 80. Summary ZIO Prelude Refinement Types will provide a solution to these problems: • Smarter Constructors with Composable Assertions that work at compile time AND at run time
  • 81. Summary ZIO Prelude Refinement Types will provide a solution to these problems: • Smarter Constructors with Composable Assertions that work at compile time AND at run time • No additional overhead because of wrapping/unwrapping
  • 82. Summary ZIO Prelude Refinement Types will provide a solution to these problems: • Smarter Constructors with Composable Assertions that work at compile time AND at run time • No additional overhead because of wrapping/unwrapping • All of this thanks to the power of Scala 3 Macros!. No weird stuff, just standard Scala