Scala中的部分函数

时间:2015-08-19 01:20:56

标签: scala

我只是想澄清一下Scala中部分定义的函数。我查看了文档,它说部分函数的类型是PartialFunction[A,B],我可以定义一个部分函数,​​如

val f: PartialFunction[Any, Int] = {...}

我想知道,对于AB类型,A是一个参数,B是一个返回类型?如果我有多个可接受的类型,我是否可以使用orElse将部分功能链接在一起?

3 个答案:

答案 0 :(得分:10)

在函数的集合理论视图中,如果函数可以将域中的每个值映射到该范围中的值,则我们说该函数是total function。可能存在这样的情况:函数无法将域中的某些元素映射到该范围;这些函数称为partial functions

以Scala文档中的部分函数为例:

val isEven: PartialFunction[Int, String] = {
  case x if x % 2 == 0 => x+" is even"
}

这里定义了部分函数,​​因为它被定义为仅将偶数整数映射到字符串。因此,partial函数的输入是一个整数,输出是一个字符串。

val isOdd: PartialFunction[Int, String] = {
  case x if x % 2 == 1 => x+" is odd"
}

isOdd是另一个部分函数,​​类似于isEven但是对于奇数。同样,partial函数的输入是一个整数,输出是一个字符串。

如果您有一个数字列表,例如:

List(1,2,3,4,5)

并在此列表中应用isEven部分功能,您将获得输出

List(2 is even, 4 is even)

请注意,并非部分函数已映射原始列表中的所有元素。但是,在某些情况下,您可能希望在部分函数无法将元素从域映射到范围的情况下应用其他函数。在这种情况下,我们使用orElse

val numbers = sample map (isEven orElse isOdd)

现在你将获得输出:

List(1 is odd, 2 is even, 3 is odd, 4 is even, 5 is odd)

答案 1 :(得分:4)

如果您要设置一个实际上需要多个参数的部分函数,​​请在您将要输入的参数元组上定义部分函数,​​例如:

val multiArgPartial: PartialFunction[(String, Long, Foo), Int] = {
  case ("OK", _, Foo("bar", _)) => 0 // Use underscore to accept any value for a given parameter
}

当然,请确保将参数作为元组传递给它。

答案 2 :(得分:0)

除了其他答案,如果通过"多个接受的类型"你的意思是你想要相同的功能接受例如StringIntBoolean(并且没有其他类型),这称为"联合类型"并且目前在Scala中不受支持(但计划将来基于Dotty)。替代方案是:

  1. 使用最不常见的超类型(Any用于上述情况)。这就是orElse链将要做的事情。
  2. 使用类似Either[String, Either[Int, Boolean]]的类型。如果你有两种类型,但很快变得难看,这很好。
  3. 将联合类型编码为negation of intersection types