Skip to content

Instantly share code, notes, and snippets.

@nicktelford
Created February 22, 2012 15:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicktelford/1885542 to your computer and use it in GitHub Desktop.
Save nicktelford/1885542 to your computer and use it in GitHub Desktop.
Alternative to PartialFunctions for Extractors - avoids double unapply calls
// pretend this extractor is performance critical
object EvenExtractor {
def unapply(x: Int): Option[Int] = {
println("Testing for EVEN: " + x)
if (x % 2 == 0) Option(x) else None
}
}
// when you use it from a PartialFunction, it gets executed TWICE for all applicable values
Seq(1, 2, 3, 4) collect {
case EvenExtractor(x) => x
}
// as an alternative, extract values manually to an Option and defer collection
Seq(1, 2, 3, 4) map {
x => EvenExtractor.unapply(x)
} collect {
case Some(x) => x
}
// but what if you have multiple extractors?
object OddExtractor {
def unapply(x: Int): Option[Int] = {
println("Testing for ODD: " + x)
if (x % 2 == 0) None else Option(x)
}
}
Seq(1, 2, 3, 4) collect {
case EvenExtractor(x) => x
case OddExtractor(x) => x
}
// chain Options with orElse!
Seq(1, 2, 3, 4) map {
x => EvenExtractor.unapply(x) orElse OddExtractor.unapply(x)
} collect {
case Some(x) => x
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment