1 of 15

Our Common Scala Library

Vlad Patryshev, HealthExpense, 2016

2 of 15

Useful Scala Features

  • strong typing
  • higher order types
  • implicits
  • closures
  • library pimping

3 of 15

Packages

  • com.healthexpense.common
    • most of the classes here
    • nlp - Natural Language Processing
    • parsing - parsers-specific functionality
    • web - Web-specific functionality

4 of 15

Important Classes

  • Result
  • Props
  • Money
  • DateAndTime
  • DateOfBirth
  • Linguist
  • Strings
  • Types
  • Ops
  • IO

5 of 15

Result[T]

It’s a monad, and an applicative functor.

val myResult: Result[A] = for {

x <- Result.valueOf(suspiciousEvaluations) orCommentTheError “oops…”

(y,z) <- Result(optionY) andAlso Result(optionZ)

} yield someCalculation(x,y,z)

6 of 15

Props

Smart and nutritious Map[String, String].

  • Like JSON, but flat
  • Can use regex to find keys
  • Can apply ‘translate’
  • Can pull subtree
  • Good for configs, for data from the web...

7 of 15

Money (dollars only)

dollars(“$-123.46”): Result[BigDecimal]

dollarsOrZero(“$$$”): BigDecimal

8 of 15

DateAndTime, DateOfBirth

  • Based on JodaTime
  • parses dates
  • formats dates
  • deals with timezones (ours is UTC, Fidelity has EST)
  • checks if the DOB is reasonable (no unborn, nobody from XIX century)

9 of 15

Linguist

  • Knows a lot about words and names
  • Matches names in a smart way
  • Matches security questions in a smart way
  • Capitalizes properly
  • Work in progress

10 of 15

Linguist Samples

firstNameOf _ named "firstNameOf" maps(

" Juan Antonio Samaranch\n the third " -> "Juan",

"Anna-Maria Kegelmeister," -> "Anna-Maria",

"Patryshev, Vlad" -> "Vlad",

" X\t\t" -> "X",

"the end" -> "the"

)

lastNameOf _ named "lastNameOf" maps(

"Patryshev, Vlad" -> "Patryshev",

" The rest is silence." -> "Silence",

"\n\n\t\fAnna-Maria Kegelmeister," -> "Kegelmeister",

"...Bond, James Bond!" -> "Bond",

"Martin Luther King Jr." -> "King",

"Bill Gates the 3rd" -> "Gates",

" X\t\t" -> ""

)

fullNamesMatch _ passesOn(

("Martin Luther King Jr.", "MARTIN KING"),

("JOSE ARCADIO BUENDIA", "Jose-Arcadio Buendia"),

("JOSE BUENDIA", "Jose-Arcadio Buendia"),

("ARCADIO BUENDIA", "Jose-Arcadio Buendia"),

("JOSE ARCADIO BUENDIA", "José Buendìa"),

("SAUL Babilona", "Saúl Babiloña"),

("Saúl Babiloña", "SAUL Babilona"),

("KADAR JANOS", "Kádár János"),

("Stephen Ng", " stephen ng "),

("JULIAXYGREK", "Julia X Ygrek"),

("Do Young O", " do o"),

("Bill Gates the 3rd", "BILL GATES"),

("Martin Luther King Jr.", "MARTIN JR")

)

11 of 15

Strings

  • Tons of functions you may need or not
  • implicit PowerString, e.g.
    • "cafebabe0f0f".decodeHex == Array(0xca,0xfe,0xba,...)
    • println("ab\"cd\"ef".quote) => "ab\"cd\"ef"
  • etc

12 of 15

Types

  • type predicate
  • type IDof[T]
  • implicit betterArray (get returns an option, etc)
  • trait ArrayOf[T]

13 of 15

Ops

  • a ? b | c
  • sleepSome(millis) - with scale
  • toSource(Map(“abc”->List(7,40)) => “Map(“abc”->List(7,40)”
  • asScala - converts old Java data to Scala
  • groupByRelationship(rel, list)
  • spendNoMoreThan(dt) on {operation}
  • caller, callerStackTrace

14 of 15

IO

  • grabResource(name)
  • propsFromFile(filename)
  • (new File(“main.scala”)).extension = “class”

val summary = for {

sourceScript <- IO.find("aws_parse.sh")

content <- Result.forValue(Source.fromFile(sourceScript).getLines().toList)

} yield ...

"""object main {

def main(args) { println("Hello") }

}""" #> "main.scala"

15 of 15

Reference

https://github.com/HealthExpense/Backend2/tree/master/src/main/scala/com/healthexpense/common

(and there’s more: see com.healthexpense.Backend2.data, com.healthexpense.Backend2.tools, etc)