我想实现一个简单的设计目标,但Scala的类型系统的复杂性让我有些头疼。 Traversable的,迭代器,可迭代,流的比较后,查看等我的决定是定义一个自定义特征(我们叫它Stream
为简洁起见),其
- 不通用(我流语义上才有意义,因为有些
Stream[StreamEntry]
我想避免这样无意义的各类Stream[Int]
- 也有类似的用法
Iterable
- 像所有成员
take
,drop
等应返回Stream
,而不是基本的Iterable
。
这是我到目前为止已经试过:
方法1
素描使用的情况下,一个简单的例子(违反第三设计目标)将是:
case class StreamEntry(data: Double) // just a dummy
trait Stream extends Iterable[StreamEntry] {
val metaInfo: String
}
// example use case
val s = new Stream {
val metaInfo = "something"
val iterator = StreamEntry(1) :: StreamEntry(2) :: StreamEntry(3) :: Nil toIterator
}
val t = s.take(1) // unfortunately, this is no longer a Stream
方法2
这第三个要求要求的模板特征 ,而不是基本特点 (我希望这是标准的术语来指SomeCollection或SomeCollectionLike)的使用。 这意味着我必须使用IterableLike[StreamEntry, Stream]
其中重新定义的返回类型的表示集合的一样Iterable
延伸IterableLike[A, Iterable[A]]
返回Iterable
秒。 我的想法是做几乎一样Iterable
一样。 这将是:
// this is exactly the way `Iterable` is defined, but non-generic
trait Stream extends Traversable[StreamEntry]
with GenIterable[StreamEntry]
with GenericTraversableTemplate[StreamEntry, Stream]
with IterableLike[StreamEntry, Stream] {
...
}
不幸的是,这并不能编译,因为Stream
显示为模板参数GenericTraversableTemplate
和编译器现在需要一个模板参数(只有一个) Stream
本身,这是有道理的。
方法3,4,...
从这里开始,我失去了我的类型系统。 仅仅取消with GenericTraversableTemplate
导致不兼容的类型newBuilder
和非法继承由于在类型参数冲突GenericTraversableTemplate
从GenInterable
和Traversable
。
也许最接近的解决方案是以下几点:
trait Stream extends TraversableLike[StreamEntry, Stream]
with IterableLike[StreamEntry, Stream] {
val metaInfo: String
def seq = this
def newBuilder: scala.collection.mutable.Builder[StreamEntry, Stream] = ???
}
这将编译但不幸的是我不知道如何实现建造。 是否有可能重新使用我的非通用特征的通用生成器? 其实我虽然我可以去没有一个Builder,因为我从来没有真正想建立一个新的Stream
从其他收藏品。 但目前我遇到这种方法,我不能完全理解一些奇怪的运行时行为。 例如:
val s = new Stream {
val metaInfo = "something"
val iterator = StreamEntry(1) :: StreamEntry(2) :: StreamEntry(3) :: Nil toIterator
}
// executing the following independently (not in sequence) results in:
s.take(1) // throws: scala.NotImplementedError: an implementation is missing
// seems to require a Builder :(
s.toArray // works
s.toIterator // works
s.toIterable // throws: java.lang.ClassCastException: cannot be cast to scala.collection.Iterable
现在我觉得有点失去了在斯卡拉型系统的深度。 我仍然是正确的轨道上利用这最后的方针,建造只是缺少一块在这个难题?
而如何将一个Builder实现样子了非一般的非缓存类型? 一个直接的想法来实现+=
是使用一些可变的缓冲,但这将是非常反对首先使用迭代器......我应该如何落实to
成员,如果我不知道如何构建一个类类型的? 我想所有相关的代码必须在某个地方的图书馆,我只是不能挖掘出来。