Scala 为什么不设置实现部分功能?

Scala 为什么不设置实现部分功能?,scala,Scala,Scala编程:全面的分步指南,第2版,第546页: 在Iterable下面的继承层次结构中,您可以找到三个特征:Seq, 设定,并绘制地图。这三个特征的一个共同点是它们都是 实现部分功能特性及其应用和定义 方法 但是,此代码不编译(2.8.2和2.10.2都尝试过): 有误: value isDefinedAt is not a member of scala.collection.immutable.Set[Int] 这是书中的错误吗?看起来确实是这样。到Scala 2.5.0: 并扩展

Scala编程:全面的分步指南,第2版,第546页:

在Iterable下面的继承层次结构中,您可以找到三个特征:Seq, 设定,并绘制地图。这三个特征的一个共同点是它们都是 实现部分功能特性及其应用和定义 方法

但是,此代码不编译(2.8.2和2.10.2都尝试过):

有误:

value isDefinedAt is not a member of scala.collection.immutable.Set[Int]

这是书中的错误吗?

看起来确实是这样。到Scala 2.5.0:

  • 并扩展部分功能:
  • 没有

这似乎很合理:
Set
将对象映射为
布尔值,因此它总是定义为
true
用于成员,
false
用于非成员)。

在数学中,部分函数
X=>Y
是一个函数
X'→ Y
,其中X'是X的子集。将部分函数命名为Set是不正确的,因为它是一个总函数,在每个元素上都定义了它

这就是为什么
Set(1,2,3).isDefinedAt\u
没有意义-它总是等于
true

如前所述,Set[T]扩展了T=>Boolean,无论元素是否存在,apply方法都会导致true或false。如果需要,可以创建

trait NamedSet[T] extends Set[T] with PartialFunction[T,Boolean] {
   def isDefinedAt(x: T) = true
}

正如您所看到的,它没有任何意义

我的猜测是,
isDefinedAt
是一个测试元素是否存在于集合中的测试程序,而
Set
apply
contains
则执行该任务。我的意思是,
Set
s通常(并非总是)仅仅用于测试元素的存在性。是的,这对我来说是明显的打字错误。@cds-
isDefinedAt
用于检查是否为给定的参数值定义了分部函数。请参见@Lee,在集合的上下文中,即存在性测试,这不是很清楚和明显吗?@CDS-它不是存在性测试,它返回函数是否为某个输入值定义,而不是返回true。如果您有类似于
valf:PartialFunction[Int,Bool]=case{1=>true}
的内容,那么
f(2)
甚至没有定义。在这种情况下,
isDefinedAt(2)
返回false,而
f(2)
将抛出一个异常。确切地说,它总是被定义的,这就是为什么
Set
扩展了
Function1[A,Boolean]
而不是
PartialFunction[A,??]
注意
FunctionN
也是部分的。在Scala中无法保证总体性。
function n
PartialFunction
之间的区别不是一个是部分的,另一个不是。不同的是,一个人知道偏爱的概念,可以被询问,而另一个人不知道。因此,
Set
不能用
isDefinedAt(:t)=true
@JörgWMittag实现
PartialFunction[t,Bool]
这一点并不像你暗示的那么明显:我想我大体上理解了你的说法(尽管我不明白你为什么说“你不能保证Scala中的总体性”——想详细说明吗?)。然而,这里的要点是,扩展
PartialFunction
会给开发人员带来一些语义权重:您看到标题,可能会想“哎呀,对某些值来说,应用它可能会以某种不寻常的方式工作”。每个
函数
扩展
部分函数
是完全正确的,但我认为这种方法没有任何好处,最大的缺点是噪音。@TheTerriblesWift番茄,Scala中的所有函数都是部分函数,这意味着函数可能无法为某些输入返回值(例如
def x(I:Int)=1/x
是部分的,因为
x(0)
的计算结果不是一个值;相反,
defy(i:Int)=i+1
是总数,因为它有一个可以传递给它的任何整数的值)。PartialFunction的子类形式化了函数的偏好性-它允许您通过
isDefinedAt
,测试函数是否会因给定的输入而终止-而不是仅仅调用它并让它返回值或发散。@Bill:true,“y”除了是total之外也是一个部分函数。这就是我在API中提到噪声的原因——要么将
PartialFunction
“可选”,用于所有函数(或者只是那些您不想以那种方式进行反思的函数),要么坚持数学定义,将每个函数都设为
PartialFunction
。但话说回来:
isDefinedAt
也是一个函数。然而,如果有人觉得我的答案在这方面有误导性,我很乐意编辑它。
trait NamedSet[T] extends Set[T] with PartialFunction[T,Boolean] {
   def isDefinedAt(x: T) = true
}