为什么PartialFunction <:功能在Scala呢?
-
06-09-2019 - |
题
在Scala中,PartialFunction[A, B]
类是从类型Function[A, B]
衍生(见的Scala参考,12.3.3)。然而,这似乎违反直觉对我来说,因为Function
(这需要所有A
待定)具有比PartialFunction
,可在一些地方是不确定的更严格的要求。
我已经来到翻过的问题是,当我具有部分功能,我不能使用Function
延长部分功能。例如。我不能做到:
(pf orElse (_)=>"default")(x)
(希望的语法是至少远程右)
这是为什么亚型反向做了什么?是否有我忽视,如事实Function
类型是内置的任何原因?
顺便说一句,它会如果Function1 :> Function0
所以不需要具有在上面的例子中的伪参数是也好看: - )
编辑澄清亚型问题
这两种方法之间的差异可以通过看两个例子加以强调。这其中是吧?
一:
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隐含的。
PartialFunction
具有方法,其Function1
不会,因此它是子类型。这些方法是isDefinedAt
和orElse
。
您真正的问题是PartialFunction
s不是有时推断,当你真的希望他们是。我希望,这将在未来的一段时间来解决。例如,这不工作:
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
不隶属于 StackOverflow