Scala 为什么不设置实现部分功能?
Scala编程:全面的分步指南,第2版,第546页: 在Iterable下面的继承层次结构中,您可以找到三个特征:Seq, 设定,并绘制地图。这三个特征的一个共同点是它们都是 实现部分功能特性及其应用和定义 方法 但是,此代码不编译(2.8.2和2.10.2都尝试过): 有误: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: 并扩展
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
}