9

由于总函数是偏函数的特例,我想我应该能够在需要偏函数时返回一个函数。

例如,

def partial : PartialFunction[Any,Any] = any => any

当然,这种语法无法编译。我的问题是,是否可以这样做,如果可以,我需要做什么才能使语法正确。

我知道我可以做以下事情,但这只是一个出于好奇的问题

def partial : PartialFunction[Any,Any] = {
  case any => any
}
4

5 回答 5

12

你可以使用PartialFunction.apply方法:

val partial = PartialFunction[Any,Any]{ any => any }

如果你想让它更短,你可以导入这个方法:

import PartialFunction.{apply => pf}
val partial = pf[Any,Any]{ any => any }
于 2014-01-02T20:32:39.437 回答
4

AFunctionN不是一个全函数:

val evilFun: Int => Int = n => if (n < 0) sys.error("I'm evil!") else n

换句话说,所有 Scala 函数都是偏函数。因此PartialFunction,只是为您提供了一种方法来检查部分函数 viaisDefinedAt和链接部分函数 via orElse

完全摆脱PartialFunction并在函数文字和提升方法isDefinedAt的层面上一如既往地实现可能是有意义的。FunctionNisDefinedAttrue

于 2014-01-02T20:45:29.397 回答
1

我想你可能已经转换了概念。

PartialFunction[-A, +B] extends (A) ⇒ B 

但是,您不能在需要子类的地方使用超类值,因为子类更具体。因此,您不能Function1从类型为返回 a 的方法返回值PartialFunction

反之亦然 -您可以在需要超类的地方使用子类。因此,您可以PartialFunction从类型化的方法返回 a 以返回 a Function1(具有相同的类型参数):

scala> def f: Any => Any = { case a => "foo" }
f: Any => Any

scala> f(1)
res0: Any = foo

在这种特殊情况下,您始终可以将 a 转换Function为 a PartialFunction,因此提供了该PartialFunction.apply方法。

def apply[A, B](f: A => B): PartialFunction[A, B] = { case x => f(x) }
于 2014-01-06T16:00:47.190 回答
0

时间已经过去了,Scala 在2.13.5并且自 Scala 2.12.5 以来已被接受的答案中显示的内容被弃用:

要将普通函数 f 转换为部分函数 pf,请使用val pf: PartialFunction[A, B] = { case x => f(x) }. 要创建新的 PartialFunction,请改用显式类型注释,如val pf: PartialFunction[Int, String] = { case 1 => "one" }.

另外,请考虑import scala.{PartialFunction => =/>}(与常规、总计、函数相反=>)。由于部分函数需要写出类型(也就是添加类型注释),这可以为您节省大量手动输入并提高可读性,例如:

val yourPf: String =/> String = {
  case SomeRegEx(s) => s
}

旁注:在我的机器上PartialFunction.apply甚至会导致错误PartialFunction.type does not take parameters

于 2021-04-12T12:36:20.240 回答
-4

我认为您正在寻找一种称为“lift”的便捷方法,它将部分函数转换为函数1(返回包含在选项中的结果)。

http://www.scala-lang.org/api/current/index.html#scala.PartialFunction

说到分类;我认为您倒退了-partialfunction是function1的子类型

于 2014-01-02T20:14:38.813 回答