@@ -693,189 +693,3 @@ object LazyList extends LazyListFactory[LazyList] {
693
693
private [this ] def writeObject (out : ObjectOutputStream ): Unit = ()
694
694
private [this ] def readObject (in : ObjectInputStream ): Unit = ()
695
695
}
696
-
697
- @ deprecated(" Use LazyList (which has a lazy head and tail) instead of Stream (which has a lazy tail only)" , " 2.13.0" )
698
- @ SerialVersionUID (3L )
699
- sealed abstract class Stream [+ A ] extends AbstractSeq [A ] with LinearSeq [A ] with LazyListOps [A , Stream , Stream [A ]] {
700
- override def iterableFactory : LazyListFactory [Stream ] = Stream
701
-
702
- override protected [this ] def className : String = " Stream"
703
-
704
- protected def cons [T ](hd : => T , tl : => Stream [T ]): Stream [T ] = new Stream .Cons (hd, tl)
705
-
706
- /** Apply the given function `f` to each element of this linear sequence
707
- * (while respecting the order of the elements).
708
- *
709
- * @param f The treatment to apply to each element.
710
- * @note Overridden here as final to trigger tail-call optimization, which
711
- * replaces 'this' with 'tail' at each iteration. This is absolutely
712
- * necessary for allowing the GC to collect the underlying LazyList as elements
713
- * are consumed.
714
- * @note This function will force the realization of the entire LazyList
715
- * unless the `f` throws an exception.
716
- */
717
- @ tailrec
718
- override final def foreach [U ](f : A => U ): Unit = {
719
- if (! this .isEmpty) {
720
- f(head)
721
- tail.foreach(f)
722
- }
723
- }
724
-
725
- override def take (n : Int ): Stream [A ] = {
726
- if (n <= 0 || isEmpty) Stream .empty
727
- else if (n == 1 ) new Stream .Cons (head, Stream .empty)
728
- else new Stream .Cons (head, tail.take(n - 1 ))
729
- }
730
-
731
- /** LazyList specialization of foldLeft which allows GC to collect along the
732
- * way.
733
- *
734
- * @tparam B The type of value being accumulated.
735
- * @param z The initial value seeded into the function `op`.
736
- * @param op The operation to perform on successive elements of the `LazyList`.
737
- * @return The accumulated value from successive applications of `op`.
738
- */
739
- @ tailrec
740
- override final def foldLeft [B ](z : B )(op : (B , A ) => B ): B = {
741
- if (this .isEmpty) z
742
- else tail.foldLeft(op(z, head))(op)
743
- }
744
-
745
- @ deprecated(" The `append` operation has been renamed `lazyAppendedAll`" , " 2.13.0" )
746
- @ inline final def append [B >: A ](suffix : IterableOnce [B ]): Stream [B ] = lazyAppendedAll(suffix)
747
-
748
- override protected [this ] def writeReplace (): AnyRef =
749
- if (headDefined && tailDefined) new LazyListOps .SerializationProxy [A , Stream ](this ) else this
750
-
751
- /** Prints elements of this stream one by one, separated by commas. */
752
- @ deprecated(message = """ Use print(stream.force.mkString(", ")) instead""" , since = " 2.13.0" )
753
- @ inline def print (): Unit = Console .print(this .force.mkString(" , " ))
754
-
755
- /** Prints elements of this stream one by one, separated by `sep`.
756
- * @param sep The separator string printed between consecutive elements.
757
- */
758
- @ deprecated(message = " Use print(stream.force.mkString(sep)) instead" , since = " 2.13.0" )
759
- @ inline def print (sep : String ): Unit = Console .print(this .force.mkString(sep))
760
-
761
- }
762
-
763
- @ deprecated(" Use LazyList (which has a lazy head and tail) instead of Stream (which has a lazy tail only)" , " 2.13.0" )
764
- @ SerialVersionUID (3L )
765
- object Stream extends LazyListFactory [Stream ] {
766
-
767
- protected def newCons [T ](hd : => T , tl : => Stream [T ]): Stream [T ] = new Stream .Cons (hd, tl)
768
-
769
- // @SerialVersionUID(3L) //TODO Putting an annotation on Stream.empty causes a cyclic dependency in unpickling
770
- object Empty extends Stream [Nothing ] {
771
- override def isEmpty : Boolean = true
772
- override def head : Nothing = throw new NoSuchElementException (" head of empty stream" )
773
- override def tail : Stream [Nothing ] = throw new UnsupportedOperationException (" tail of empty stream" )
774
- /** Forces evaluation of the whole `Stream` and returns it.
775
- *
776
- * @note Often we use `Stream`s to represent an infinite set or series. If
777
- * that's the case for your particular `Stream` then this function will never
778
- * return and will probably crash the VM with an `OutOfMemory` exception.
779
- * This function will not hang on a finite cycle, however.
780
- *
781
- * @return The fully realized `Stream`.
782
- */
783
- def force : this .type = this
784
- override def knownSize : Int = 0
785
- override def iterator : Iterator [Nothing ] = Iterator .empty
786
- protected def headDefined : Boolean = false
787
- protected def tailDefined : Boolean = false
788
- }
789
-
790
- @ SerialVersionUID (3L )
791
- final class Cons [A ](override val head : A , tl : => Stream [A ]) extends Stream [A ] {
792
- private [this ] var tlEvaluated : Boolean = false
793
- override def isEmpty : Boolean = false
794
- override lazy val tail : Stream [A ] = {
795
- tlEvaluated = true
796
- tl
797
- }
798
- protected def headDefined : Boolean = true
799
- protected def tailDefined : Boolean = tlEvaluated
800
- /** Forces evaluation of the whole `Stream` and returns it.
801
- *
802
- * @note Often we use `Stream`s to represent an infinite set or series. If
803
- * that's the case for your particular `Stream` then this function will never
804
- * return and will probably crash the VM with an `OutOfMemory` exception.
805
- * This function will not hang on a finite cycle, however.
806
- *
807
- * @return The fully realized `Stream`.
808
- */
809
- def force : this .type = {
810
- // Use standard 2x 1x iterator trick for cycle detection ("those" is slow one)
811
- var these, those : Stream [A ] = this
812
- if (! these.isEmpty) these = these.tail
813
- while (those ne these) {
814
- if (these.isEmpty) return this
815
- these = these.tail
816
- if (these.isEmpty) return this
817
- these = these.tail
818
- if (these eq those) return this
819
- those = those.tail
820
- }
821
- this
822
- }
823
-
824
- }
825
-
826
- /** An alternative way of building and matching Streams using Stream.cons(hd, tl).
827
- */
828
- object cons {
829
- /** A stream consisting of a given first element and remaining elements
830
- * @param hd The first element of the result stream
831
- * @param tl The remaining elements of the result stream
832
- */
833
- def apply [A ](hd : A , tl : => Stream [A ]): Stream [A ] = new Cons (hd, tl)
834
-
835
- /** Maps a stream to its head and tail */
836
- def unapply [A ](xs : Stream [A ]): Option [(A , Stream [A ])] = #:: .unapply(xs)
837
- }
838
-
839
- implicit def toDeferrer [A ](l : => Stream [A ]): Deferrer [A ] = new Deferrer [A ](() => l)
840
-
841
- final class Deferrer [A ] private [Stream ] (private val l : () => Stream [A ]) extends AnyVal {
842
- /** Construct a Stream consisting of a given first element followed by elements
843
- * from another Stream.
844
- */
845
- def #:: [B >: A ](elem : B ): Stream [B ] = new Cons (elem, l())
846
- /** Construct a Stream consisting of the concatenation of the given Stream and
847
- * another Stream.
848
- */
849
- def #::: [B >: A ](prefix : Stream [B ]): Stream [B ] = prefix lazyAppendedAll l()
850
- }
851
-
852
- object #:: {
853
- def unapply [A ](s : Stream [A ]): Option [(A , Stream [A ])] =
854
- if (s.nonEmpty) Some ((s.head, s.tail)) else None
855
- }
856
-
857
- def from [A ](coll : collection.IterableOnce [A ]): Stream [A ] = coll match {
858
- case coll : Stream [A ] => coll
859
- case _ => fromIterator(coll.iterator)
860
- }
861
-
862
- /**
863
- * @return A `Stream[A]` that gets its elements from the given `Iterator`.
864
- *
865
- * @param it Source iterator
866
- * @tparam A type of elements
867
- */
868
- // Note that the resulting `Stream` will be effectively iterable more than once because
869
- // `Stream` memoizes its elements
870
- def fromIterator [A ](it : Iterator [A ]): Stream [A ] =
871
- if (it.hasNext) {
872
- new Stream .Cons (it.next(), fromIterator(it))
873
- } else Stream .Empty
874
-
875
- def empty [A ]: Stream [A ] = Empty
876
-
877
- // scalac generates a `readReplace` method to discard the deserialized state (see https://github.com/scala/bug/issues/10412).
878
- // This prevents it from serializing it in the first place:
879
- private [this ] def writeObject (out : ObjectOutputStream ): Unit = ()
880
- private [this ] def readObject (in : ObjectInputStream ): Unit = ()
881
- }
0 commit comments