Цепные операции над значениями без именования промежуточных значений - PullRequest
5 голосов
/ 06 марта 2019

Иногда я выполняю последовательность вычислений, постепенно преобразовывая какое-то значение, например:

def complexComputation(input: String): String = {
  val first = input.reverse
  val second = first + first
  val third = second * 3
  third
}

Имена переменных иногда бывает громоздкой, и я хотел бы избежать этого.Один из шаблонов, который я использую для этого, - это цепочка значений, используя Option.map:

def complexComputation(input: String): String = {
  Option(input)
    .map(_.reverse)
    .map(s => s + s)
    .map(_ * 3)
    .get
}

Используя Option / get, однако для меня это не совсем естественно.Есть ли другой способ, которым это обычно делается?

Ответы [ 2 ]

7 голосов
/ 06 марта 2019

На самом деле это будет возможно с Scala 2.13 . Он введет трубу :

import scala.util.chaining._

input //"str"
 .pipe(s => s.reverse) //"rts"
 .pipe(s => s + s) //"rtsrts"
 .pipe(s => s * 3) //"rtsrtsrtsrtsrtsrts"

Версия 2.13.0-M1 уже выпущена. Если вы не хотите использовать версию Milestone, возможно, стоит рассмотреть возможность использования backport ?

1 голос
/ 06 марта 2019

Как вы упомянули, можно реализовать pipe самостоятельно, например:

implicit class Piper[A](a: A) {
  def pipe[B](f: A => B) = {
    f(a)
  }
}

val res = 2.pipe(i => i + 1).pipe(_ + 3)
println(res)  // 6

val resStr = "Hello".pipe(s => s + " you!")
println(resStr)  // Hello you!

или взглянуть на https://github.com/scala/scala/blob/v2.13.0-M5/src/library/scala/util/ChainingOps.scala#L44.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...