0

多くの場合、次のような関数があります。

{
  val x = foo;
  bar(x);
  x
}

たとえば、barはしばしば のようなものLog.debugです。

それを実行するためのより短く、慣用的な方法はありますか? たとえば、次のような組み込み関数

def act[A](value: A, f: A => Any): A = { f(value); value }

私はただ書くことができるようにact(foo, bar _)

4

3 に答える 3

1

書かれたとおりに関数を使用するactことは、私にとって完全に慣用的なようです。組み込みの方法はわかりませんが、この種のものをどこでも使用する「コモンズ」または「ユーティリティ」プロジェクトに入れるだけです。

bar 関数が通常同じである場合 (Log.debug など)、そのための特定のラッパー関数を作成することもできます。例えば:

def withDebug[A](prefix: String)(value: A)(implicit logger: Logger): A = {
  logger.debug(prefix + value)
  value
}

次のように使用できます。

implicit val loggerI = logger

def actExample() {
  // original method
  val c = act(2 + 2, logger.debug)

  // a little cleaner?
  val d = withDebug("The sum is: ") {
      2 + 2
    }
  }

または、さらに多くの構文シュガーについては、次のようにします。

object Tap {
  implicit def toTap[A](value: A): Tap[A] = new Tap(value)
}

class Tap[A](value: A) {

  def tap(f: A => Any): A = {
    f(value)
    value
  }

  def report(prefix: String)(implicit logger: Logger): A = {
    logger.debug(prefix + value)
    value
  }
}

object TapExample extends Logging {
  import Tap._
  implicit val loggerI = logger

  val c = 2 + 2 tap { x => logger.debug("The sum is: " + x) }

  val d = 2 + 2 report "The sum is: "

  assert(d == 4)
}

Wheretapは任意の関数を取り、reportロガーをラップするだけです。もちろん、他の一般的に使用されるタップをTapクラスに追加することもできます。

于 2013-07-10T14:56:07.540 に答える
0

Scala にはすでに構文的に重いバージョンが含まれていることに注意してください。

foo match { case x => bar(x); x }

しかし、短いバージョン ( tapRuby で同じ名前を使用することをお勧めします) を作成すると、利点が得られます。

于 2013-07-10T15:11:38.850 に答える