@@ -3,17 +3,24 @@ package collection
33
44import strawman .collection .mutable .Builder
55
6- import scala .{Any , Int }
6+ import scala .{Any , Int , Nothing }
77import scala .annotation .unchecked .uncheckedVariance
88
99/** Instances of Build[B] can build some kind of collection from values of type B. */
1010trait Build [- B ] {
1111 type To [_]
1212 def fromIterable [E <: B ](it : Iterable [E ]): To [E ]
1313}
14+ trait BuildStrict [- B ] extends Build [B ] {
15+ def newBuilder [E <: B ]: Builder [E , To [E ]]
16+ }
1417
18+ /** Instances of BuildConstrained can build some kind of collection from values with an implicit constraint. */
1519trait BuildConstrained {
16- trait Constraint [E ] extends Build [E ]
20+ trait Constraint [E ] <: Build [E ]
21+ }
22+ trait BuildStrictConstrained extends BuildConstrained {
23+ trait Constraint [E ] extends super .Constraint [E ] with BuildStrict [E ]
1724}
1825
1926/** Base trait for instances that can construct a collection from an iterable */
@@ -24,12 +31,12 @@ trait FromIterable[+C[_]] extends Build[Any] {
2431
2532/** Base trait for instances that can construct a collection from an iterable by using an implicit evidence
2633 * for the element type. */
27- trait ConstrainedFromIterable [+ CC [_], Ev [_]] {
34+ trait ConstrainedFromIterable [+ CC [_], Ev [_]] extends BuildConstrained {
2835 def constrainedFromIterable [E : Ev ](it : Iterable [E ]): CC [E ]
2936}
3037
3138/** Base trait for companion objects of unconstrained collection types */
32- trait IterableFactory [+ C [_]] extends FromIterable [C ] { self =>
39+ trait IterableFactory [+ C [_]] extends FromIterable [C ] with BuildStrict [ Any ] { self =>
3340 def empty [A ]: C [A ] = fromIterable(View .Empty )
3441
3542 def apply [A ](xs : A * ): C [A ] = fromIterable(View .Elems (xs : _* ))
@@ -38,21 +45,33 @@ trait IterableFactory[+C[_]] extends FromIterable[C] { self =>
3845
3946 def newBuilder [A ]: Builder [A , C [A ]]
4047
41- protected [this ] lazy val canBuildProto : CanBuild [Any , C [Any ]] = new CanBuild [Any , C [Any ]] {
42- def fromIterable (it : Iterable [Any ]): C [Any ] = self.fromIterable[Any ](it)
43- def newBuilder : Builder [Any , C [Any ]] = self.newBuilder[Any ]
48+ protected [this ] lazy val buildFromProto : BuildFrom [C [Any ], Any ] = new BuildFrom [C [Any ], Any ] {
49+ type To [_] = C [Any ]
50+ def fromIterable [E ](it : Iterable [E ]): C [Any ] = self.fromIterable[Any ](it)
51+ def newBuilder [E ]: Builder [E , C [Any ]] = self.newBuilder[Any ]
4452 }
4553
46- implicit def canBuild [E ]: CanBuild [E , C [E ]] = canBuildProto.asInstanceOf [CanBuild [E , C [E ]]]
54+ implicit def buildFrom [F , E ]: BuildFrom [C [F ], E ] { type To [_] <: C [E ] } =
55+ buildFromProto.asInstanceOf [BuildFrom [C [F ], E ] { type To [_] <: C [E ] }]
56+
57+ def buildFromAny [E ]: BuildFrom [Nothing , E ] { type To [_] <: C [E ] } =
58+ buildFromProto.asInstanceOf [BuildFrom [Nothing , E ] { type To [_] <: C [E ] }]
4759}
4860
49- trait CanBuild [ E , + Repr ] {
50- def fromIterable ( it : Iterable [E ]) : Repr
51- def newBuilder : Builder [ E , Repr ]
61+ /** Implicit instances of this type are available for building arbitrary collection types */
62+ trait BuildFrom [ + Repr , E ] extends BuildStrict [E ] { self =>
63+ def any : BuildFrom [ Nothing , E ] { type To [ X ] = self. To [ X ] } = this . asInstanceOf [ BuildFrom [ Nothing , E ] { type To [ X ] = self. To [ X ] } ]
5264}
5365
5466/** Base trait for companion objects of collections that require an implicit evidence */
55- trait ConstrainedIterableFactory [+ CC [X ], Ev [_]] extends ConstrainedFromIterable [CC , Ev ] {
67+ trait ConstrainedIterableFactory [+ CC [X ], Ev [_]] extends ConstrainedFromIterable [CC , Ev ] with BuildStrictConstrained {
68+
69+ class ConstraintImpl [E : Ev ] extends Constraint [E ] {
70+ type To [_] = CC [E ] @ uncheckedVariance
71+ def fromIterable [X <: E ](it : Iterable [X ]): CC [E ] = constrainedFromIterable[E ](it)
72+ def newBuilder [X <: E ]: Builder [X , CC [E ]] = constrainedNewBuilder[E ]
73+ }
74+ implicit def constraint [E : Ev ]: ConstraintImpl [E ] = new ConstraintImpl [E ]
5675
5776 def empty [A : Ev ]: CC [A ] = constrainedFromIterable(View .Empty )
5877
@@ -62,8 +81,12 @@ trait ConstrainedIterableFactory[+CC[X], Ev[_]] extends ConstrainedFromIterable[
6281
6382 def constrainedNewBuilder [A : Ev ]: Builder [A , CC [A ]]
6483
65- implicit def canBuild [E : Ev ]: CanBuild [E , CC [E ]] = new CanBuild [E , CC [E ]] {
66- def fromIterable (it : Iterable [E ]): CC [E ] = constrainedFromIterable[E ](it)
67- def newBuilder : Builder [E , CC [E ]] = constrainedNewBuilder[E ]
84+ implicit def buildFrom [F , E : Ev ]: BuildFrom [CC [F ], E ] { type To [_] <: CC [E ] } = new BuildFrom [CC [F ], E ] {
85+ type To [_] = CC [E ]
86+ def fromIterable [X <: E ](it : Iterable [X ]): CC [E ] = constrainedFromIterable[E ](it)
87+ def newBuilder [X <: E ]: Builder [X , CC [E ]] = constrainedNewBuilder[E ]
6888 }
89+
90+ def buildFromAny [E : Ev ]: BuildFrom [Nothing , E ] { type To [_] <: CC [E ] } =
91+ buildFrom[Any , E ].asInstanceOf [BuildFrom [Nothing , E ] { type To [_] <: CC [E ] }]
6992}
0 commit comments