2

次の例を見てみましょう。最初の呼び出しの結果を一時的に保存してそれに対して照合するのではなく、エクストラクタが複数回呼び出されるのはなぜですか。unapply同じ文字列が与えられた場合、結果は変わらないと仮定するのは合理的ではないでしょうか。

object Name {
  val NameReg = """^(\w+)\s(?:(\w+)\s)?(\w+)$""".r

  def unapply(fullName: String): Option[(String, String, String)] = {
    val NameReg(fname, mname, lname) = fullName
    Some((fname, if (mname == null) "" else mname, lname))
  }
}

"John Smith Doe" match {
  case Name("Jane", _, _) => println("I know you, Jane.")
  case Name(f, "", _) => println(s"Hi ${f}")
  case Name(f, m, _) => println(s"Howdy, ${f} ${m}.")
  case _ => println("Don't know you")
}
4

2 に答える 2

1

unapply同じ文字列が与えられた場合、結果は変わらないと仮定するのは合理的ではないでしょうか。

残念ながら、 (静的) コンパイラーにとっては、この想定では十分ではありません。メモ化が合法的な最適化であるためには、コンパイラーは、メモ化される式が純粋で参照透過であることを証明する必要があります。ただし、一般的なケースでは、これは停止問題を解くことと同じです。

特定の式の純粋性を証明しようとし、成功した場合にのみそれらをメモする最適化パスを作成することは確かに可能ですが、それは価値があるよりも面倒な場合があります。そのような証明は非常に急速に困難になるため、とにかく非常に迅速に実行される非常に自明な式に対してのみ成功する可能性があります。

于 2014-12-16T11:17:21.233 に答える