My talk for the 38th Meetup of the Scaladores (the Scala developers community os São Paulo - Brazil), which happened on March 22, 2018 on 99 Taxis office.
In this talk, I introduced the concept of Refined Types through the "refined library" and how it can make Scala's static typing even more robust.
Unfortunately, the slides are (mostly) in Portuguese.
2. Marcelo Gomes
• Nasceu na pequena Juiz de Fora - MG
• Morou 9 anos no Rio
• Já mexeu com Delphi, Java, Ruby e
Objective-C
• Agora mora em São Paulo e trabalha
com Scala
3. Pra quê servem refined types?
• Tipagem forte e estática é muito legal! (com inferência
então…)
• O compilador ajuda a evitar um monte de erros bobos
• Mas na maior parte do tempo, isso não basta…
11. object SpBus {
type IdRange = Interval.Closed[W.`10000`.T, W.`89999`.T]
type LineRegex = MatchesRegex[
W.`"""^[1-8][0-9L][0-9][0-9A-Z]-d{2}$"""`.T]
type MinSizeString =
MinSize[W.`3`.T] And
Not[MatchesRegex[W.`"""^s+$"""`.T]]
}
case class SpBus(
id: Int Refined IdRange,
line: String Refined LineRegex,
company: String Refined MinSizeString
)
12. Agora, isso não compila mais!
import eu.timepit.refined.auto._
val bus = SpBus(
id = 0,
line = "SV917",
company = “”
)
13. Para valores não hardcoded, age como validação!
def buildBus(
id: Int,
line: String,
company: String): Either[String,SpBus] = {
for {
id <- refineV[IdRange](id)
line <- refineV[LineRegex](line)
company <- refineV[MinSizeString](company)
} yield SpBus(id, line, company)
}
14. Não se pode ter tudo na vida…
import eu.timepit.refined.auto._
type NonEmptyPositiveList =
NonEmpty And Forall[Positive]
val x: List[Int] Refined NonEmptyPositiveList =
List(1,2,3,4,5,6,7,8,9)
“compile-time refinement only works with literals”
15. Mas não perca a esperança!
import eu.timepit.refined.auto._
type NonEmptyValidInts = NonEmpty And Forall[ValidInt]
type AllPositiveInts = Forall[Positive]
type PositiveIntList = List[Int] Refined AllPositiveInts
def parse(s: String): Either[String,PositiveIntList] = {
val validatedStringList =
refineV[NonEmptyValidInts](s.split(",").toList)
val validatedIntList = validatedStringList
.flatMap { stringList =>
val intList = stringList.map{ _.toInt }
refineV[AllPositiveInts](intList)
}
validatedIntList
}
parse("1,2,3,4,5,6")