Oop 为什么Seq[V]不扩展映射[Int,V],也不设置[V]扩展映射[V,Bool]?
Oop 为什么Seq[V]不扩展映射[Int,V],也不设置[V]扩展映射[V,Bool]?,oop,scala,subclass,Oop,Scala,Subclass,Iterable的三个直接子类型是Map、Seq和Set。似乎除了性能问题之外,Seq是从整数到值的映射,Set是从值到布尔值的映射(如果值在集合中,则为true,否则为false) 如果是这样的话,为什么不在类型系统中通过使Seq[V]extendMap[Int,V]和Set[V]extendMap[V,Boolean]来表示这一点呢?好吧,至少它们确实有一些共同的功能Seq[B]继承自Int=>B(通过PartialFunction[Int,B]),Map[A,B]继承自A=>B(也通过Pa
Iterable
的三个直接子类型是Map
、Seq
和Set
。似乎除了性能问题之外,Seq
是从整数到值的映射,Set
是从值到布尔值的映射(如果值在集合中,则为true,否则为false)
如果是这样的话,为什么不在类型系统中通过使
Seq[V]
extendMap[Int,V]
和Set[V]
extendMap[V,Boolean]
来表示这一点呢?好吧,至少它们确实有一些共同的功能Seq[B]
继承自Int=>B
(通过PartialFunction[Int,B]
),Map[A,B]
继承自A=>B
(也通过PartialFunction[A,B]
),以及Set[A]
继承自A=/code>。因此,就函数应用和组合方法而言,这三种方法都可以互换使用。此外,它们可以在遍历过程中互换使用,因为它们都实现了可遍历性,就像
那么,如果您只关心Seq
和Set
的话,那么您就有理由了。我自己,我碰巧认为这是最不重要的方面之一,并且已经很好地用函数来表示了
也就是说,Map
是键到值的函数,Seq
是Int
到值的函数,Set
是值到布尔值的函数。此属性(您称之为“映射”)是一个函数。这三个国家都已经分享了
在我看来,Map
、Seq
和Set
实际上是关于:
Seq
关心的是知道其元素的顺序。从概念上讲,如何在映射中预先添加元素?你得把所有的钥匙重新编号
集合
与元素的存在或不存在有关。在地图中如何建模?它必须是一个具有默认值的映射,而不是一个公共映射,并且其中所有非默认值都相同!这显然是一种堕落的行为,而不是抽象
Map
涉及将任意键映射到任意值。Seq
没有任意键,Set
没有任意值
将序列看作是从整数到元素的赋值,这只是描述序列的一种方式。还有其他的方法,而且没有理由认为这种描述序列的方法应该成为规范的。序列的实际目的是使一组元素可以访问和遍历。为元素实际分配整数不需要序列。例如,大多数流
实现可能没有与遍历并行运行的计数器。要求这样做会给实现带来不必要的开销
此外,Map[K,V]
也是一个Iterable[(K,V)]
。按照您的建议,aSeq[a]
也必须是一个Map[Int,a]
,这也将使它成为一个Iterable[(Int,a)]
。由于Seq
扩展了Iterable
,这将使Seq[A]
既成为Iterable[A]
又成为Iterable[(Int,A)]
(以及递归地成为Iterable[(Int,(Int,A))
,Iterable[(Int,(Int,(Int,A))]
,等等),这在Scala中是不允许的继承方式
关于Set
Set
和Seq
与Map
的语义非常不同,因此以这种方式公开它们是没有意义的。@Gabe,你能举一个具体的例子说明“不同的语义”是什么意思吗?我认为这是一个有趣的问题,但马多克的回答是决定性的。这里有一些有趣/相关的讨论:我认为第二个论点很有说服力。为了简化它,如果Seq[A]
extendedMap[Int,A]
,那么Seq.elements()
会返回什么?有趣。Haskell的类型系统没有这样的限制(事实上,它标榜这种左右多态性)。看到Scala的基本理论如何限制其标准库很有趣。@Adam我也不认为Haskell能从中摆脱出来。如果您在Haskell中将foldr
作为列表,则不会折叠元组(Int,A)
:您可以折叠A
。谢谢!在这种情况下,我想我的问题有点转移:映射[a,B]和函数[a,B]之间的基本区别是什么,30个字或更少?@Adam aMap
是可遍历的,而函数
不是。因此,映射
可以枚举它的键,但是函数
不能对它的参数做同样的操作。“好吧,如果你所关心的一切”——好吧,我的问题可以重新表述为“Scala库设计人员关心的是什么导致他们做出这个决定”?@Adam See,and。