Scala extractors simplified
Extractors seem to be nothing more than lifted and wrapped PartialFunction
s:
type ?=>[A, B] = PartialFunction[A, B]
trait Extractor[A, B] { def unapply(x: A): Option[B] }
def Extractor[A, B](fn: A ?=> B) = new Extractor[A, B] {
def unapply(x: A): Option[B] = fn.lift(x)
}
Let's use that framework on some data:
val people = List(
Person("Bradley", "Smith"),
Person("Paul", "Freeman", Some(Position("Programmer"))),
Person("Mary", "Martyr", Some(Position("Manager", Some(Company("IBM", Some(1881)))))))
Now we have the option to define an extractor to get the company a person works at, if any, or instead start out with a more bare bones function; let's go bare bones first:
val getCompany: Person ?=> Company = {
case Person(_, _, Some(Position(_, Some(c)))) => c
}
We'd have to use longer syntax here if instead of getCompany
we'd defined a full blown extractor straight away:
val companies = people.collect(getCompany).distinct
Now we can convert getCompany
into an extractor called EmployedAt
for added pattern matching convenience:
val EmployedAt = Extractor(getCompany)
Extractors compose better in more complex pattern matching queries:
def getEmployees(company: Company) =
people.collect { case p @ EmployedAt(`company`) => p }
Written by Erik Allik
Related protips
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
#Scala
Authors
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#