0

部分関数を使用してメッセージを処理するクラスのクラス階層を定義したいと考えています。各クラスは、処理できないメッセージをそのスーパークラスに延期する必要があります。このようなもの:

type Respond = PartialFunction[String, String]

abstract class HandlesNothing {
  def respond: Respond = Map.empty // the empty response. Handles nothing
}

class HandlesA extends HandlesNothing {
  override def respond = { case "a" => "The letter A" } orElse super.respond
}

class HandlesAAndB extends HandlesA {
  override def respond = { case "b" => "The letter B" } orElse super.respond
}

あなたはアイデアを得る。しかし、これを試してみると、次のエラーが表示されます

<console>:21: error: missing parameter type for expanded function
The argument types of an anonymous function must be fully known. (SLS 8.5)
Expected type was: ?
         override def respond = { case "b" => "The letter B" } orElse super.respond
                                ^

{...} ブロックの型を明示的に指定すると、次のように機能します。

class HandlesAAndB extends HandlesA {
  override def respond = ({ case "b" => "The letter B" }:Respond) orElse super.respond
}

部分関数ブロックの型を明示的に指定せずにこれを達成する方法はありますか?

4

2 に答える 2

2

orElse問題は、右側が存在する場合、メソッドの戻り値の型によって、左側の型が適切に指定されていないことです。(また、LHS は構文上、必ずしも部分的な関数ではありません。不完全に指定されている可能性がありますFunction1。) 概念的にさえ、コンパイラはここで少し追加の助けがなければ正しいことを実行できないため、次のことを行う必要があります。何かをします。

: Respondしたがって、残っている唯一の問題は、左辺の型を示すよりも良い方法があるかどうかです。答えはおそらく次のとおりです。

implicit class Resp(val underlying: Respond) extends AnyVal {
  def or(r: Respond) = underlying orElse r
}

abstract class A { def respond: Respond = Map.empty }
class B extends A {
  override def respond = Resp{ case "A" => "The letter A" } or super.respond
}

暗黙の値クラスを使用するおかげで、この方法で行うことによるオーバーヘッドは本質的にありません。コストは、標準的な Scala ライブラリ呼び出しの代わりにカスタムのミニ DSL を使用することです。

于 2013-07-12T19:09:17.800 に答える