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
}

由于使用了隐式值类,这样做基本上没有开销。代价是你有一个定制的 mini-DSL 而不是普通的 Scala 库调用。

于 2013-07-12T19:09:17.800 回答
1

你可以这样做:

abstract class HandlesNothing {
  def respond: Respond = Map.empty // the empty response. Handles nothing
  protected def c(supPf: Respond)(pf: Respond) = pf orElse supPf
}

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

诚然,这很丑陋,但可以节省您的打字时间。

探索过程中发现的有趣细节:无法绑定superthis. 那真的很酷。

于 2013-07-12T19:01:29.530 回答