Scala: Matching Reusable Samples

Given this case of pattern matching:

foo match {
    case x if expensiveCalculation(x).nonEmpty => // do something with expensiveCalculation(x)
...
}

Is it possible to β€œlabel” or reuse expensiveCalculation(x)after =>?

Ideally, I expected something like:

foo match {
        case x val ec = expensiveCalculation(x); if ec.nonEmpty => // do something with ec
    ...
    }
+4
source share
2 answers

You can write an extractor for the type x(assumed here InputType):

object Expensive {
  def unapply(x: InputType): Option[OutputType] = expensiveCalculation(x)
}

Now you can use it according to your template:

fooList match {
  case _ :: Expensive(output) :: _ => ...
  case _ :: x :: _ => ...
}

However, this is a cumbersome way to do what you want if you do it for many calculations (you need to define an extractor each time).

You can do this once and for all by specifying the following:

case class Comput[-A, +B](f: A => Option[B]) {
  def unapply(a: A): Option[B] = f(a)
}

Now you can use it as follows:

val intString = "10"
val IntOf = Comput[String, Int](s => Try(s.toInt).toOption)

intString match {
  case IntOf(x) => x
  case other => 0
} // returns 10: Int

IntOf, (, , ).

+1

, , .

. , ,

fooList match {
  case _ :: x :: _ if expensiveCalculation(x).nonEmpty => // do something with expensiveCalculation(x)
  ...
}

,

fooList match {
  case _ :: x :: _ => expensiveCalculation(x) match {
    case Some(calculationResult) => ....
    case None =>
  }
  ...
}
0

Source: https://habr.com/ru/post/1660770/


All Articles