Scala部分函数与具体部分函数
有没有什么快速的方法可以作为一个具体的函数(例如,Scala部分函数与具体部分函数,scala,partialfunction,Scala,Partialfunction,有没有什么快速的方法可以作为一个具体的函数(例如,(a)=>B)作为部分函数[a,B]?我所知道的最简洁的语法是: (a: A) => a match { case obj => func(obj) } 是否在任何地方都存在隐式转换,例如: implicit def funcAsPartial[A, B](func: A => B) = new PartialFunction[A, B] { def isDefinedAt(a: A) = true def appl
(a)=>B
)作为部分函数[a,B]
?我所知道的最简洁的语法是:
(a: A) => a match { case obj => func(obj) }
是否在任何地方都存在隐式转换,例如:
implicit def funcAsPartial[A, B](func: A => B) = new PartialFunction[A, B] {
def isDefinedAt(a: A) = true
def apply(a: A) = func(a)
}
我想我只是写了我想要的东西,但是Scala库中已经有了吗?没有,几个月前我试着找到了一个,结果我自己写了一个,基本上和你的一样。用隐式转换做这件事是危险的,原因与
(a)相同=>B
不应从部分函数[A,B]
继承。也就是说,PartialFunction的契约保证您可以在isDefinedAt
返回true
的任何位置安全地*调用apply
。职能1的合同未提供此类担保
如果将隐式转换应用于未在任何地方定义的函数,则会导致PartialFunction违反其约定。相反,使用皮条客明确转换:
implicit def funcAsPartial[A, B](f: A => B) = new {
/** only use if `f` is defined everywhere */
def asPartial(): PartialFunction[A, B] = {
case a => f(a)
}
def asPartial(isDefinedAt: A => Boolean): PartialFunction[A, B] = {
case a if isDefinedAt(a) => f(a)
}
}
// now you can write
val f = (i: Int) => i * i
val p = f.asPartial // defined on all integers
val p2 = f.asPartial(_ > 0) // defined only on positive integers
*正如评论中所讨论的,这里“安全”的含义可能并不完全清楚。我的想法是,PartialFunction明确声明其域的精确含义如下:如果
isDefinedAt
为值x
返回true,那么apply(x)
可以按照函数作者的意图进行计算。这并不意味着apply(x)
不会抛出异常,而仅仅是异常是函数设计的一部分(应该记录在案)。在我看来(A)=>B
应该继承自部分函数[A,B]
,而不是相反。我同意这一点,因为A(total)函数是一个局部函数,碰巧在任何地方都定义了(isDefinedAt(x)=true)但是,Martin Odersky说,函数不能保证是一个完整的函数,只是它的域没有文档记录。所以PartialFunction是一个记录其域的函数。谢谢;我有一个错误的想法,即Function1意味着在整个域上定义。@AaronNovstrup:您对PartialFunction契约的解释是唯一有意义的,但ScalaDocs(至少在2.9.1之前)没有反映出来。PartialFunction
的ScalaDocs声称:“类型为PartialFunction[A,B]
的部分函数是一元函数,其中域不一定包含类型为A
的所有值。”此外,他们从不声称在定义的任何地方调用f都是安全的(在什么意义上),这很容易违反,就像PartialFunction
literal{case 0=>1/0}
。你是从哪里得到这些信息的?是否需要提交错误报告?@Blaisorblade我相信我在学习Scala时(已经有一段时间了)在邮件列表上读到了这个解释,我在写这个答案时没有看任何文档。是的,违反这个合同很容易,甚至有些常见(例如,在catch块中包装/重新显示异常)。真正的问题是,partialfunction定义了它们的域,而普通函数则没有定义它们的域(这实际上意味着什么)@Blaisorblade文档可能应该按照我刚才添加到答案中的更改进行修订。在搜索现有的错误报告时,我从Odersky找到了以下解释-与您阅读的内容相符:。我为文档创建了一个错误报告,如前所述,链接回此处并引用您的姓名和建议: