模式匹配:使用PartialFunction拆分代码?

时间:2017-04-04 15:32:36

标签: scala pattern-matching partialfunction partial-functions

我正在努力实现一个简单的"行为:在两个独立的函数中划分模式匹配代码。

为了清晰起见,我简化了模型:

x(0)

我想在不同的函数上对这些函数进行模式匹配(因为实际代码很长),但还有其他参数,所以PartialFunctions给了我生病...
在一个完美的世界里,我可以写:

abstract class Animal
case object Dog extends Animal
case object Cat extends Animal
case object Bird extends Animal
case object Bat extends Animal
case object Dolphin extends Animal

然而,这不起作用。主要是因为我在函数中需要多个参数。 "为什么你不使用元组?"你可以说?好吧,我试过,编译器不会停止抱怨预期的类型与实际类型不同,并且与我的别名不同:(

任何帮助,提示或其他想法都会有用! 干杯

编辑: 我跟着Cyrille的回答我还需要在赛前做一些工作,比如:

type PF = PartialFunction[(Animal, Int, String), String] 
private def processFlying(a: Animal, n: Int, loc: String): PF = {
  a match {
    case Bird => n + " birds found in " + loc
    case Bat => n + " bats found in " + underground(loc)
  }
}
private def processMarine(a: Animal, n: Int, loc: String): PF = {
  a match {
    case Dolphin => n + " dolphins found in " + submarine(loc)
  }
}
private def processPet(a: Animal, n: Int, loc: String): PF = {
  a match {
    case Dog => n + " dogs found in " + loc
    case Cat => n + " cats found in " + loc
  }
}
def processAnimal(a: Animal, number: Int, location: String) = {
  val processAll = processFlying orElse processMarine orElse processPet
  processAll(a, n, location)
}

1 个答案:

答案 0 :(得分:2)

您的问题是您正在混合方法定义和函数定义。

def processFlying(a: Animal, n: Int, loc: String): PF

是(周围对象的)方法的签名,它接受三个参数并返回PF,即PartialFunction[(Animal, Int, String), String]

因此,假设此签名符合您的要求,只有PartialFunctionAnimalInt,您才能获得String ...

你更可能想要的是定义一个PF值(没有参数),所以更像是

val processFlying: PF = {
  case (Bird, n, loc) => ...
  case (Bat, n, loc) => ...
}

修改

要回答你的第二个请求(虽然它可能有点过分,因为将你的助手定义为私有def会完成这项工作),你总是可以将PF块放在一个闭包中:

val processFlying = {
  def f = ...
  val res = {
    case (Bird, n, loc) => f(...)
    case (Bat, n, loc) => f(...)
  }
  res
}

但是,您必须为PartialFunction定义块分配值,否则解析器将无法知道如何处理它。这只是因为PartialFunction定义与case的块和闭包共享{}语法。