为什么Scala中的PartialFunction <:Function?

在Scala中, PartialFunction[A, B]类是从Function[A, B]types派生的(参见Scala参考,12.3.3)。 但是,这对我来说似乎是违反直觉的,因为一个Function (需要为所有A定义)比PartialFunction有更严格的要求,在某些地方可能是未定义的。

我遇到的问题是,当我有一个部分函数,​​我不能使用Function来扩展部分函数。 例如。 我不能做:

 (pf orElse (_)=>"default")(x) 

(希望语法至less是远程的权利)

为什么这个子types是相反的? 是否有任何我忽略的原因,比如Functiontypes是内置的?

顺便说一句,如果Function1 :> Function0 ,这也不错,所以我不需要在上面的例子中有伪参数:-)

编辑澄清子types问题

两种方法的区别可以通过两个例子来强调。 哪一个是对的?

一:

 val zeroOne : PartialFunction[Float, Float] = { case 0 => 1 } val sinc = zeroOne orElse ((x) => sin(x)/x) // should this be a breach of promise? 

二:

 def foo(f : (Int)=>Int) { print(f(1)) } val bar = new PartialFunction[Int, Int] { def apply(x : Int) = x/2 def isDefinedAt(x : Int) = x%2 == 0 } foo(bar) // should this be a breach of promise? 

因为在Scala中(就像在任何图灵语言中一样),不能保证函数是完整的。

 val f = {x : Int => 1 / x} 

该函数没有被定义为0. PartialFunction只是一个函数,可以告诉你它没有被定义在哪里。 不过,斯卡拉可以很容易地做你想做的事情

 def func2Partial[A,R](f : A => R) : PartialFunction[A,R] = {case x => f(x)} val pf : PartialFunction[Int, String] = {case 1 => "one"} val g = pf orElse func2Partial{_ : Int => "default"} scala> g(1) res0: String = one scala> g(2) res1: String = default 

如果你愿意,你可以使func2Partial隐式。

PartialFunctionFunction1没有的方法,因此它是子types。 这些方法是isDefinedAtorElse

你真正的问题是,当你真的喜欢他们的时候, PartialFunction不是被推断出来的。 我希望这将在未来的某个时候解决。 例如这不起作用:

 scala> val pf: PartialFunction[String, String] = { case "a" => "foo" } pf: PartialFunction[String,String] = <function> scala> pf orElse { case x => "default" } <console>:6: error: missing parameter type for expanded function ((x0$1) => x0$1 match { case (x @ _) => "default" }) 

但是这样做:

 scala> pf orElse ({ case x => "default" } : PartialFunction[String,String]) res5: PartialFunction[String,String] = <function> 

当然你可以这样做:

 scala> implicit def f2pf[T,R](f: Function1[T,R]): PartialFunction[T,R] = new PartialFunction[T,R] { def apply(x: T) = f(x) def isDefinedAt(x: T) = true } f2pf: [T,R](f: (T) => R)PartialFunction[T,R] 

现在更像你想要的:

 scala> pf orElse ((x: String) => "default") res7: PartialFunction[String,String] = <function> scala> println(res7("a") + " " + res7("quux")) foo default