部分関数
Scala では、aPartialFunction
は要するに、isDefinedAt
メソッドを追加で定義する関数です。
一連のcase
ステートメントで部分関数を定義するのは簡単です。些細な例は、たとえば次のようになります。
scala> val pf: PartialFunction[Int, Unit] = {
| case 42 => ()
| }
pf: PartialFunction[Int,Unit] = <function1>
scala> pf.isDefinedAt(42)
res0: Boolean = true
scala> pf.isDefinedAt(0)
res1: Boolean = false
isDefinedAt
case
部分関数を定義する のリストから自動的に生成されます。
環境
Lift フレームワークは、リクエストを Lift のエンジンで処理するか、ディスク上のファイルからそのまま処理するかを定義するなど、多くの場所で部分関数を使用します。また、case
すべての入力パラメーターに一致するステートメントを作成し、値を返すかどうかを後で決定したいと思うこともあります。これは、最初の一連のcase
s では、関数が特定の値で定義されているかどうかを判断するのに十分ではないことを意味します
たとえば、Lift では、すべての html および htm ファイルが直接提供され、拡張子が「lift」のファイルを処理する必要があるというルールを追加したいと考えています。次のようなことをするのは簡単に見えます:
LiftRules.liftRequest.prepend {
case Req(path, extension, tpe) => extension match {
case "html" | "htm" => false
case "lift" => true
}
}
残念ながら、この場合、コンパイラは、最初の関数がcase
常に一致するため、部分関数がどこでも定義されていると見なします。match
すべての受信リクエストに一致しない可能性があるのは、ネストされたものです。そして、リクエストが一致しない場合は、 aMatchError
がスローされます。
質問
match
部分関数を定義するときにコンパイラにネストされたステートメントを考慮させる簡単な方法はありますか、またはこのようにネストされたすべての条件をインライン化する唯一の方法はありますか?
LiftRules.liftRequest.prepend {
case Req(path, extension, tpe) if extension == "html" || extension == "htm" => false
case Req(path, extension, tpe) if extension == "lift" => true
}
この例では、ほとんど実行可能ですが、可読性が低下し、すべてのチェックをインライン化すると非常に見苦しく見えるケースに直面しました。